Implementing virtual dispatch in D

maik klein via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Mar 19 18:30:05 PDT 2016


So this is mostly curiosity and not completely related to D but I 
would like to know how a vtable is actually implemented. All the 
explanations that I have seen so far are a bit vague and it would 
be nice to actually see some code.

I tried to implement the following myself

interface Something{
    void print();
    int getNumber();
}

This is how I would do it:

struct VDispatch(Types...){
     void* vptr;
     char typeId;

     void print(){
         foreach(index, type; Types){
             if(index == typeId){
                 (cast(type*)vptr).print();
             }
         }
     }

     int getNumber(){
         foreach(index, type; Types){
             if(index == typeId){
                 return (cast(type*)vptr).getNumber();
             }
         }
         throw new Error("Unknown Type");
     }

     this(T)(T* ptr){
         import std.meta: staticIndexOf;
         vptr = cast(void*)ptr;
         typeId = staticIndexOf!(T, Types);
     }
}


struct Foo{
     int number;
     void print(){
         import std.stdio;
         writeln("Foo: ", number);
     }
     int getNumber(){
         return number;
     }
}

struct Bar{
     int number;
     void print(){
         import std.stdio;
         writeln("Bar: ", number);
     }
     int getNumber(){
         return number;
     }
}

unittest{
     import std.stdio;
     alias VFooBar = VDispatch!(Foo, Bar);
     auto t = VFooBar(new Foo(42));
     auto t1 = VFooBar(new Bar(24));
     t.print();
     t1.print();
     writeln(t.getNumber());
     writeln(t1.getNumber());
}

Is this how it works internally? I assume the compiler would 
generate which types actually supported at runtime? I have 
modeled this as a variadic template "Types..." and it has to be 
managed by the user.



More information about the Digitalmars-d-learn mailing list