Pages

Tuesday, December 25, 2012

Compile time reflection in C++


 *This is an example of the wasted brain cycles C++ forces on us because it lacks common sense stuff like modules & compile time reflection*

Unfortunately C++ does not have reflection--compile time or otherwise. It might be added in C++17, but I needed it *now*.

 So I wrote a macro using the Boost Preprocessor library to generate compile time reflection data within a class.

 A Reflected object looks like this:
 After macro evaluation this generates an embedded type called "Reflection".
 The Reflection structure contains N sub types labled [Member1 - MemberN], and an enum indicating how many members are present.

 Each Member structure then contains the following data.

1. The type: (Member::type)
2. Access to member pointer (Member::GetMemberPtr())
3. Access to name of the reflected member (Member::GetName())
4. A type which indicates if the member is a function or variable, and if it is static or not(Member::member_class)
4. Optional meta data(basically user defined attributes). (Member::meta)

 The meta tags can be optionally attached like so:

 PP_Reflect(Test,
           ((_member)(Serialize)(Replicate)) //Serialize and Replicate being types you have declared 
           ((_static_member))
           ((MemberFuntion))
           ((StaticMemberFuntion)))


 You then need some compile time functionality to walk this and generate something useful out of it.

Dealing with inherited base types is not difficult, you just need to add a type list which lists any base types, and then have your evaluation functions walk the full hierarchy.

 Here is a link to the code if you are interested: reflection

 Uses decltype and auto so some C++11 conformance is required.

1 comment: