Boost logo

Boost Users :

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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net