D RTTI?
Artur Skawina
art.08.09 at gmail.com
Wed Mar 7 15:04:58 PST 2012
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
More information about the Digitalmars-d-learn
mailing list