D RTTI?

Jacob Carlborg doob at me.com
Tue Mar 6 23:40:29 PST 2012


On 2012-03-07 00:19, H. S. Teoh wrote:
> On Tue, Mar 06, 2012 at 11:40:19PM +0100, Artur Skawina wrote:
>> On 03/06/12 20:37, H. S. Teoh wrote:
>>> On Tue, Mar 06, 2012 at 01:51:51AM +0100, Artur Skawina wrote:
>>> [...]
>>>> class A {
>>>>     string prop1;
>>>>     int prop2;
>>>>
>>>>     void serialize(this THIS)() {
>>>>        __serialize(cast(THIS*)&this);
>>>>     }
>>>> }
>>>>
>>>> void __serialize(T)(T* obj) {
>>>>     writef("%s {\n", typeid(*obj));
>>>>     foreach (name; __traits(allMembers, T)) {
>>>>        static if (__traits(compiles,&__traits(getMember,obj,name))) {
>>>>           alias typeof(__traits(getMember,obj,name)) MT;
>>>>           static if (is(MT==function))
>>>>              continue;
>>>>           else {
>>>>              auto m = __traits(getMember,obj,name);
>>>>              if (is(MT:const(char[])))
>>>>                 writef("   %s %s = \"%s\";\n", typeid(MT), name, m);
>>>>              else
>>>>                 writef("   %s %s = %s;\n", typeid(MT), name, m);
>>>>           }
>>>>        }
>>>>     }
>>>>     writef("}\n");
>>>> }
>>>>
>>>> And it will do the right thing for derived classes too.
>>> [...]
>>>
>>> Hmm, it only does the right thing for derived class if invoked with the
>>> derived class pointer. It doesn't work (and in retrospect can't possibly
>>> work, since "this THIS" is a compile-time parameter) if you only have
>>> the base class pointer.
>>
>> Of course. But is it really necessary to fully serialize derived classes
>> *w/o* knowing what they are? In that case deserialization will probably be
>> "interesting" too...
>
> It's easy. We already output the class name in the serialization, so to
> deserialize, we just call Object.factory(class_name), then a per-class
> deserialize() method similar to the above that reconstructs class data.

That only works for classes with no constructor, or a default 
constructor, which sucks. It's fairly easy to implement your own version 
that does not call constructors.

>>> What I needed was for serialize() to be polymorphic at runtime, so it
>>> does have to be overloaded in every derived class. Hmph...  looks like I
>>> can't avoid using mixins. :-(
>>
>> If you can "register" the classes to be serialized then typeid() can
>> help the __serialize() implementation...
>
> True. But TypeInfo doesn't let you access actual data members without
> using void* casts and pointer arithmetic, whereas compile-time
> introspection does.

There are ways around that, have a look in my serialization library 
Orange: https://github.com/jacob-carlborg/orange


-- 
/Jacob Carlborg


More information about the Digitalmars-d-learn mailing list