D Paste by downs
Description: cpp_demo.d
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | module cpp_demo; import tools.cpp, tools.ctfe, tools.base; extern(C) { void destr(string S)(void* p) { printf("Destructor of %s says hi\n", S); } alias CppClass!("type_info", AbstractMethod!(void function(void*), "destr"), // destructor AbstractMethod!(bool function(void*), "__is_pointer_p"), AbstractMethod!(bool function(void*), "__is_function_p"), AbstractMethod!(bool function(void*, void**, int, void*), "__do_catch"), AbstractMethod!(bool function(void*, void**, void*), "__do_upcast"), Member!(char*, "name") ) type_info; enum Flags { non_diamond_repeat = 0x1, diamond_shaped = 0x2, non_public_base = 0x4, public_base = 0x8, unknown = 0x10 } enum SubKind { unknown = 0, not_contained, contained_ambig, contained_virtual_mask = 0x1, contained_public_mask = 0x2, contained_mask = 1 << 2, contained_private = contained_mask, contained_public = contained_mask | contained_public_mask } struct dyncast_result { void* dst_ptr; SubKind whole2dst, whole2src, dst2src; Flags whole_details; static dyncast_result opCall(Flags f) { dyncast_result res; res.whole_details = f; return res; } } bool dyncast_class(void* _self, ptrdiff_t src2dst, int access_path, void* _dst_type, void** obj_ptr, void* _src_type, void* src_ptr, ref dyncast_result res) { auto src_type = cast(class_type_info*) _src_type, dst_type = cast(class_type_info*) _dst_type, self = cast(class_type_info*) _self; // printf("__do_dyncast@%s(%i, %i, %s, %p, %s, %p, %p)\n", self.name, src2dst, access_path, dst_type.name, obj_ptr, src_type.name, src_ptr, res); res.dst_ptr = src_ptr - C.offset_A + C.offset_B; res.whole_details = Flags.unknown; res.whole2dst = SubKind.contained_public; res.whole2src = SubKind.contained_public; res.dst2src = SubKind.not_contained; return false; } alias CppClass!("class_type_info", type_info, VirtualMethod!(destr!("class_type_info"), "destr"), AbstractMethod!(bool function(void*, void*, void*, void*), "__do_upcast"), VirtualMethod!(dyncast_class, "__do_dyncast"), AbstractMethod!(void* function(ptrdiff_t, void*, /*class_type_info*/void*, void*, void*), "__do_find_public_src") ) class_type_info; struct base_class_info { int offset_flags; } // multiple inheritance template vmi_class_type_info(int Bases) { /*bool vmi_dyncast(void* _self, ptrdiff_t src2dst, int access_path, void* _dst_type, void* obj_ptr, void* _src_type, void* src_ptr, ref dyncast_result res) { auto src_type = cast(class_type_info*) _src_type, dst_type = cast(class_type_info*) _dst_type, self = cast(info*) _self; // fuck this shit I ain't writing the whole thing }*/ alias CppClass!("vmi_class_type_info_"~ctToString(Bases), class_type_info, // VirtualMethod!(vmi_dyncast, "__do_dyncast"), Member!(Flags, "flags"), Member!(int, "base_count"), Member!(base_class_info[Bases], "bases"), VirtualMethod!(destr!("vmi_class_type_info"), "destr") ) info; } mixin(haaax(` A { int x; virtual void test(); virtual void test2() = 0; } B { int y; virtual void test2() = 0; virtual void test3(A*) = 0; } C: A, B { virtual void test() { printf("test here with %s\n", self.get_type_info!(type_info*).name); } void test2() { printf("test2 here with %s\n", self.get_type_info!(type_info*).name); } void test3(A* a) { printf("test3 here with %p, %p -> %s, %s\n", self, a, self.get_type_info!(type_info*).name, a.get_type_info!(type_info*).name); } }`)); class_type_info _ZTI1A, _ZTI1B; vmi_class_type_info!(2).info _ZTI1C; static this() { _ZTI1A.name = "A"; _ZTI1B.name = "B"; version(GNU) { } else { _ZTI1C.fixup_vtable(); } C.fixup_classinfo(_ZTI1C.cast_type_info); with (_ZTI1C) { name = "C"; flags = Flags.unknown; base_count = 2; bases[0] = base_class_info(C.offset_A); bases[1] = base_class_info(C.offset_B); } } C* temp; A* _Z3genv() { temp = new C; version(GNU) { } else { temp.fixup_vtable(); } temp.x = 15; temp.y = 12; printf("Allocated C: %p\n", cast(void*) temp); return temp.cast_A; } void _Z6cppfunv(); } void main() { _Z6cppfunv(); } |