Pages

Tuesday, December 25, 2012

Compile time reflection in C++


 *This is an example of why C++ needs compile time reflection(and modules)*

Unfortunately C++ does not have reflection--compile time or otherwise. It might be added in C++17, but here is one way of doing it now.

 It uses 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)))


 Some compile time functionality to walk this and generate something useful out of it is then needed.

Dealing with inherited base types is not difficult,  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: