Boost logo

Boost Users :

Subject: [Boost-users] [Q] opinion on basic C++ reflection implementation
From: V S P (toreason_at_[hidden])
Date: 2009-02-28 11:21:50


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<string,tField> tName2Fields;
   typedef map<string,tFset__field> tMFset__field;
   typedef map<string,tFget__field> 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<int, all the static map pointers, funct pointers> field1;

}

------------ cpp for my class has the static maps -- -----------

-- 
  V S P
  toreason_at_[hidden]
-- 
http://www.fastmail.fm - Faster than the air-speed velocity of an
                          unladen european swallow

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