#include #include #include struct MetaObjectProperty { typedef boost::any(*property_accessor_fn_t)(void *); const char *name; property_accessor_fn_t accessor; }; template boost::any accessor(void *t) { return static_cast(t)->*MemberVariable; } struct MetaObjectBase { typedef void*(*cast_fn_t)(void *); struct MetaObject *meta_object; cast_fn_t derived_to_base; // Don't know how useful this is... cast_fn_t base_to_derived; }; template void* cast_to_base(void* p) { return static_cast(static_cast(p)); } template void* cast_to_derived(void *p) { return &dynamic_cast(*static_cast(p)); } struct MetaObject { const char *name; MetaObjectBase *bases; MetaObjectProperty *properties; }; #define REFLECTED \ virtual \ MetaObject& meta_object() \ { return static_meta_object; } \ \ static MetaObject static_meta_object // An object system struct Object { REFLECTED; std::string id; // every object has an id }; static MetaObjectBase Object_meta_object_base [] = { {0} }; static MetaObjectProperty Object_meta_object_properties[] = { {"id",accessor}, {0} }; MetaObject Object::static_meta_object = { "Object", Object_meta_object_base, Object_meta_object_properties }; struct NamedObject : Object { REFLECTED; std::string name; }; static MetaObjectBase NamedObject_meta_object_base [] = { { &Object::static_meta_object, cast_to_base, cast_to_derived }, {0} }; static MetaObjectProperty NamedObject_meta_object_properties [] = { {"name",accessor}, {0} }; MetaObject NamedObject::static_meta_object = { "NamedObject", NamedObject_meta_object_base, NamedObject_meta_object_properties }; struct Person : NamedObject { REFLECTED; std::string email_address; }; static MetaObjectBase Person_meta_object_base [] = { { &NamedObject::static_meta_object, cast_to_base, cast_to_derived }, {0} }; static MetaObjectProperty Person_meta_object_properties[] = { {"email_address",accessor}, {0,0} }; MetaObject Person::static_meta_object = { "Person", Person_meta_object_base, Person_meta_object_properties }; int indent = 0; struct doindent { doindent(std::ostream & os): m_os(os) { indent += 4; } ~doindent() { indent -= 4; } std::ostream& begin() { for(int ii = 0; ii < indent; ++ii) m_os.put(' '); return m_os; } std::ostream & m_os; }; void reflect(void * object,const MetaObject & meta) { doindent stream(std::cout); stream.begin() << "Type: " << meta.name << std::endl; MetaObjectBase * current_base = meta.bases; while(current_base && current_base->meta_object) { reflect(current_base->derived_to_base(object), *current_base->meta_object); ++current_base; } MetaObjectProperty * current_property = meta.properties; while(current_property && current_property->name) { stream.begin() << "Property: " << current_property->name << ". Value: "; boost::any value(current_property->accessor(object)); if(typeid(std::string) == value.type()) { std::cout << boost::any_cast(value) << std::endl; } else { std::cout << "Not a string type" << std::endl; } ++current_property; } } int main() { Person p; p.id = "oid:7"; p.name = "Sohail"; p.email_address = "sohail@taggedtype.net"; reflect(&p,p.meta_object()); }