|
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