#include #include #include #define A_UID 1 #define B_UID 2 #define C_UID 3 #define D_UID 4 typedef struct TypeId { char *name; int (*cast)(int); } TYPE_ID; typedef struct Info { TYPE_ID *id; int offset ; } INFO; typedef struct Object { INFO *info; } OBJECT; void *perform_cast(int uid, OBJECT *obj) { int offs=obj->info->id->cast(uid); if (offs==-1) return NULL; else return (char*)obj+obj->info->offset+offs; } typedef struct A_info A_INFO; typedef struct A_class A; typedef struct A_fld { int q; } A_FLD; struct A_class { A_INFO *info; A_FLD fld; }; typedef struct A_vt { void (*m1)(A*, int); int (*m2)(A*); } A_VT; struct A_info { TYPE_ID *id; int offset ; A_VT a_vt; }; void a_m1(A *self, int p){ self->fld.q+=p; } int a_m2(A *self){ return self->fld.q; } int a_cast(int uid) { return uid==A_UID?0:-1; } TYPE_ID a_id={"A", a_cast}; A_INFO a_info = { &a_id, 0, {a_m1, a_m2} }; A *new_A() { A *a; a=(A*)malloc(sizeof(A)); a->info=&a_info; return a; } void A_ctor(A *self){ self->fld.q=10; } typedef struct B_info B_INFO; typedef struct B_class B; typedef struct C_class C; C* new_C(); void C_ctor(C *self, int p); typedef struct D_class D; D* new_D(); void D_ctor(D *self, int o, int p); typedef struct B_fld { A *a_ptr; C *w; D *e; } B_FLD; struct B_class { B_INFO *info; B_FLD b_fld; A_INFO *info2; A_FLD a_fld; }; typedef struct B_vt { int (*m3)(B*); } B_VT; struct B_info { TYPE_ID *id; int offset ; A_VT a_vt; B_VT b_vt; }; void b_m1(A *self_a, int p); int b_m3(B *self){ return self->info2->a_vt.m2((A*)self); } int b_cast(int uid) { switch (uid) { case A_UID: return offsetof(B, info2); case B_UID: return 0; default: return -1; } } TYPE_ID b_id={ "B", b_cast }; B_INFO b_info={ &b_id, 0, {b_m1, a_m2}, {b_m3} }; A_INFO b_info2={ &b_id, -offsetof(B, info2), {b_m1, a_m2} }; B *new_B(){ B *b; b=(B*)malloc(sizeof(B)); b->info=&b_info; b->info2=&b_info2; b->b_fld.a_ptr=(A*)((char*)b+offsetof(B, info2)); A_ctor(b->b_fld.a_ptr); return b; } void B_ctor(B *self, int f) { if (f==1) { self->b_fld.w=new_C(); C_ctor(self->b_fld.w, 8); self->b_fld.e=new_D(); D_ctor(self->b_fld.e, 16, 24); } } typedef struct C_info C_INFO; typedef struct C_fld { A *a_ptr; int r; } C_FLD; struct C_class { C_INFO *info; C_FLD c_fld; A_INFO *info2; A_FLD a_fld; B_FLD b_fld; }; typedef struct C_vt { } C_VT; struct C_info { TYPE_ID *id; int offset; A_VT a_vt; B_VT b_vt; C_VT c_vt; }; void c_m1(A *self_a, int p){ C *self=(C*)perform_cast(C_UID, (OBJECT*)self_a); self->c_fld.r = p; } int c_cast(int uid) { switch(uid) { case A_UID: return offsetof(C, info2); case C_UID: return 0; default: return -1; } } TYPE_ID c_id={"C",c_cast}; C_INFO c_info={ &c_id, 0, {c_m1, a_m2}, {b_m3}, { } }; A_INFO c_info2={ &c_id, -offsetof(C, info2), {c_m1, a_m2} }; C* new_C(){ C* c; c=(C*)malloc(sizeof(C)); c->info=&c_info; c->info2=&c_info2; c->c_fld.a_ptr=(A*)((char*)c-c->info2->offset); A_ctor(c->c_fld.a_ptr); return c; } void C_ctor(C *self, int p) { B_ctor((B*)(self), 0); self->c_fld.r=p; } void b_m1(A *self_a, int p) { B *self = (B*)perform_cast(B_UID, (OBJECT*)self_a); if (self->b_fld.w!=NULL){ self->b_fld.w->info->a_vt.m1((A*)self->b_fld.w, p); }; } typedef struct D_info D_INFO; typedef struct D_fld { int t, y; } D_FLD; struct D_class { D_INFO *info; D_FLD d_fld; C_INFO *info2; C_FLD c_fld; }; typedef struct D_vt { } D_VT; struct D_info { TYPE_ID *id; int offset; A_VT a_vt; B_VT b_vt; C_VT c_vt; D_VT d_bt; }; int d_cast(int uid) { switch(uid) { case A_UID: return offsetof(D, info2); case D_UID: return 0; default: return -1; } } int d_m3(B *self_b){ D *self=(D*)perform_cast(D_UID, (OBJECT*)self_b); return self->d_fld.t-self->d_fld.y; } TYPE_ID d_id={"D", d_cast}; D_INFO d_info={ &d_id, 0, {c_m1, a_m2}, {d_m3}, {}, {} }; C_INFO d_info2={ &d_id, -offsetof(D, info2), {c_m1, a_m2}, {b_m3} }; D* new_D() { D *d; d=(D*)malloc(sizeof(D)); d->info=&d_info; d->info2=&d_info2; return d; } void D_ctor(D *self, int o, int p) { C_ctor((C*)(self), 0); self->d_fld.t=o; self->d_fld.y=p; } int main() { int i; A *a=new_A(); A_ctor(a); a->info->a_vt.m1(a, 1); i=a->info->a_vt.m2(a); B *b=new_B(); B_ctor(b, 1); b->info->a_vt.m1((A*)b, 2); i=b->info->b_vt.m3(b); C *c=new_C(); C_ctor(c, 2); c->info->a_vt.m1((A*)c, 3); D *d=new_D(); D_ctor(d, 3, 4); i=d->info->b_vt.m3((B*)d); free(a); free(b->b_fld.w); free(b->b_fld.e); free(b); free(c); free(d); return 0; }