1 module ut.refraction.vtable; 2 3 4 import ut; 5 import tardy.refraction; 6 import std.meta: AliasSeq; 7 static import std.traits; // because refract uses it 8 9 10 struct Struct { 11 import modules.types: Point; 12 13 int const_() const; 14 Point point() const; 15 int pure_() const pure; 16 void inc(int amount); 17 void safeInc(int amount) @safe; 18 void scopeInc(int amount) @safe scope; 19 } 20 21 alias functions = AliasSeq!( 22 Struct.const_, 23 Struct.point, 24 Struct.pure_, 25 Struct.inc, 26 Struct.safeInc, 27 Struct.scopeInc, 28 ); 29 30 //pragma(msg, ""); 31 static foreach(F; functions) { 32 // pragma(msg, "F: ", std.traits.fullyQualifiedName!F, "\t\t", vtableEntryRecipe!F); 33 mixin(vtableEntryRecipe!F, " ", vtableEntryId!F, ";"); 34 // pragma(msg, ""); 35 } 36 // pragma(msg, ""); 37 38 39 @("return") 40 @safe pure unittest { 41 static foreach(F; functions) { 42 shouldMatchReturnType!F; 43 } 44 } 45 46 private void shouldMatchReturnType(alias F)() { 47 import std.traits: ReturnType; 48 import std.conv: text; 49 enum vtableEntry = vtableEntryId!F; 50 static assert(is(ReturnType!F == ReturnType!(mixin(vtableEntry))), 51 text("Wrong return type for " ~ __traits(identifier, F), 52 ": expected ", ReturnType!F.stringof, " but got ", ReturnType!(mixin(vtableEntry)).stringof)); 53 } 54 55 56 @("self.mutable") 57 @safe pure unittest { 58 shouldMatchSelf!(Struct.inc, void*); 59 } 60 61 62 @("self.const") 63 @safe pure unittest { 64 shouldMatchSelf!(Struct.const_, const(void)*); 65 } 66 67 68 private void shouldMatchSelf(alias F, T)() { 69 import std.conv: text; 70 import std.traits: Parameters; 71 72 enum vtableEntry = vtableEntryId!F; 73 alias params = Parameters!(mixin(vtableEntry)); 74 75 static assert(is(params[0] == T), 76 text("Wrong self type for ", __traits(identifier, F), 77 ": expected ", T.stringof, " but got ", params[0].stringof)); 78 } 79 80 81 @("type.struct.inc") 82 @safe pure unittest { 83 static assert(is(typeof(mixin(vtableEntryId!(Struct.inc))) == void function(void*, int) @system)); 84 } 85 86 87 @("type.struct.safeInc") 88 @safe pure unittest { 89 alias T = typeof(mixin(vtableEntryId!(Struct.safeInc))); 90 static assert(is(T == void function(void*, int) @safe)); 91 } 92 93 94 // FIXME: dmd bug 95 @("type.struct.scopeInc") 96 @safe pure unittest { 97 alias T = typeof(mixin(vtableEntryId!(Struct.scopeInc))); 98 //static assert(is(T == void function(scope void*, int) @safe)); 99 } 100 101 102 private string vtableEntryId(alias F)() 103 in(__ctfe) 104 do 105 { 106 return "asvtable_" ~ __traits(identifier, F); 107 }