xxxxxxxxxx
struct Vtable{
size_t offset;
size_t function(void* ) getId;
}
struct Base{
immutable Vtable* vptr;
this(immutable Vtable* vptr){
assert(vptr !is null);
this.vptr = vptr;
}
size_t getId(){
return vptr.getId((cast(void*)&this) - vptr.offset);
}
}
struct Foo(size_t id){
static immutable Vtable vtable;
Base base;
this(typeof(null) nil){
this.base = Base(&vtable);
}
static size_t virtual_getId(Foo* foo){
return id;
}
static void vtable_init(){
Vtable* vtable = cast(Vtable*)&vtable;
vtable.offset = base.offsetof;
vtable.getId = cast(typeof(Vtable.getId))&virtual_getId;
}
}
pragma(crt_constructor)
extern(C)void shared_static_this(){
Foo!1.vtable_init();
Foo!2.vtable_init();
//Foo!3.vtable_init();
}
extern(C) void main(){
auto foo1 = Foo!1(null);
auto foo2 = Foo!2(null);
auto foo3 = Foo!3(null);
Base* b1 = &foo1.base;
Base* b2 = &foo2.base;
Base* b3 = &foo3.base;
assert(b1.getId() == 1);
assert(b2.getId() == 2);
//assert(b3.getId() == 3); //vtable is not initialized
}