Hi, I think you have the right idea. I'm also interested in this. Some quick googling brought up: http://boost-extension.redshoelace.com/docs/boost/extension/boost_extension/... but not before I had written the attached which looks like Qt's object system. The main difference between yours is that the metadata is initialized statically (or so I think!) This would get rid of that pesky mutex you have. Would be nice for Boost to have reflection capabilities but it is quite complicated to cover the whole C++ language (which is why Qt's has so many limitations.) V S P wrote:
Hello to be make it easy to read a table from a database and save the result with boost serialization (and to write back back to the database)
I have devised a scheme to achieve C++ reflections that allows me to set a field value and get a field value using a string data member name.
I am using the fact that in C++ functions can take a reference to a class instance and operate on the class data members, where the functions have hardcoded the datamember names. Since those functions can be declared as static, I simply remember the pointer to my getters and setters in static maps associated with every class instance
So when a class instance gets created -- it updates the static maps of getters and setters. I do not like the fact that I have to use a mutex on the function maps.
ANd in general wanted to ask if such approach has been implemented in one of the boost libraries or if not ... why not
I am attaching a 'brief' of the mechanism. Thank you in advance for any feedback.
Vlad -------------------------------------------------------------
struct tField { string name; //other DB-related attributes //order of declaration, isnullable, otltype }
struct reflectable {
//returns a string name of the field char* (*tF_get_field_name)(void),
//assign a value to the field. The value is obtained from functor //that's why we call it 'set' typedef void (*tFset__field)(reflecatble& , CFFunctorAssignVal&) ;
//send the field value (const) to somewhere //that's why we call it 'get' typedef void (*tFget__field)(const reflectable&,CFFunctorReceiveVal&) ;
typedef map
tName2Fields; typedef map tMFset__field; typedef map tMFget__field; //derived classes must have the "static" version of the maps //we inforce it by declaring abstract functions here //also each class will have to provide a static function //that gets returns a pointer to each map };
tempate < typename T, //cpp type tF_get_field_name fname, //function ptr to get name tFset__field assing_functor, //functor pointer to assing val to field tFget__field get_functor, //functor to read val from field
tName2Fields* ptrFieldMap, tMFset__field* ptrSetterMap, tFget__field* ptrGetterMap
struct rffield { //register a field name (obtained from fname() //with ptrFieldMap
//register pointer to getter with ptrGetterMap //register pointer to setter with ptrSetMap
}
---- separate header -----------------
struct myclass: public reflecatble { static allTheMaps...;
//to simplify I have a macro that takes in field name, cpp type //and declares them and generates getter and setter functions //that accept functors
static void field1__getter ( const reflectable&th,CFFunctorReceiveVal& f) { f(th.field1); } static void field1__setter ( const reflectable& th,CFFunctorAssignVal& f) { f(th.field1); }
static const char* field1__name (void) { const char* res="field1"; return res; }
//single declration causes all the registration to take place //since I am passing parameteres to rffield constructor //via template. It is almost like ability to invoke constructor // right in a header file. rffield
field1; }
------------ cpp for my class has the static maps -- -----------
-- Sohail Somani http://uint32t.blogspot.com