On 03/07/12 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. [...] >>> 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.
What i meant is something like this: int prop2; void serialize(this THIS)() { + if (auto p = typeid(this) in serializers) + (*p)(&this); + else __serialize(cast(THIS*)&this); } } @@ -14,6 +17,13 @@ int propB2; } +alias void delegate(void*) SDG; +SDG[typeof(typeid(int))] serializers; + +void __register(T)(T* o) { + serializers[typeid(T)] = cast(SDG)(T* o) { __serialize(o); }; +} + void __serialize(T)(T* obj) { writef("%s {\n", typeid(*obj)); foreach (name; __traits(allMembers, T)) { which doesn't need mixins in every derived class, you just need to call __register with an instance once, before doing the serializing. [it's a quick hack, written while typing this email; in real code you probably want to stick to just one approach and assert when trying to serialize an unknown type etc] artur