One of the ways I do this is to annotate identifiers:
- Classes
- base classes
- class members
- transfers
- numerators
eg:.
class MyClass : MyBaseClass { int member_; };
This annotation makes it easy to write a python or perl script that reads the header line by line and retrieves the annotation and its associated identifier.
Annotations and an associated identifier allow you to generate C ++ reflection in the form of function templates that intersect objects that pass base classes and members to a functor, for example:
template<class Functor> void reflect(MyClass& obj, Functor f) { f.on_object_start(obj); f.on_base_subobject(static_cast<MyBaseClass&>(obj)); f.on_member(obj.member_); f.on_object_end(obj); }
It is also convenient to create numeric identifiers (enumeration) for each base class and member and pass this to the functor, for example:
f.on_base_subobject(static_cast<MyBaseClass&>(obj), BaseClassIndex<MyClass>::MyBaseClass); f.on_member(obj.member_, MemberIndex<MyClass>::member_);
This reflection code allows you to write functors that serialize and de-serialize any type of object to / from several different formats. Functors use function overload and / or type inference for the proper treatment of various types.
source share