$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2008-01-29 12:34:40
AMDG
Joseph Fradley wrote:
>
> I have a problem that I would like to solve in the most generic 
> non-intrusive way possible (such as boost serialization). What I want 
> is to access class members both via it's initially designed accessors 
> but also via a "const char *"  key. In addition, I want to pass list 
> of key's (via a vector of const char * or a single delimited multikey 
> char *) to get nested member access.
>
> For example:
> ...
> // these should be equivalent
> Point p;
> int val;
> val = p.x;
> val = p.getX();
> p.getMemberValue("x", val);
>
> // there also
> Rectangle r;
> int val;
> Point pVal;
> r.getMemberValue("corner:x", val);
> r.getMemberValue("corner", pVal);
>
You could try something along these lines:
class indexable_base {
public:
    virtual indexable_base* lookup(const char*) = 0;
    virtual const std::type_info& get_type() = 0;
    virtual void* get() = 0;
};
Then you can put macros in the derived class like so:
class Rectangle : public indexable_base {
    DEFINE_LOOKUP() {
        DECLARE_VARIABLE(corner);
    }
    Point Corner;
};
Which would expand to something like
class Rectangle : public indexable_base {
    template<class T>
    void getMemberValue(const char* key, T& out) {
        indexable_base result = lookup(key);
        if(typeid(T) == result->get_type()) {
            out = *(static_cast<T*>(result->get()))
        } else {
            throw(std::bad_cast());
        }
    }
    indexable_base* lookup(const char* key) {
        // split key at ":" and lookup call lookup_ recursively until 
all the keys are used up.
    }
    static void init() {
        map_.insert(std::make_pair("corner", 
&boost::bind(&Rectangle::corner, _1)));
    }
    Point corner;
};
In Christ,
Steven Watanabe