1 /** 2 Makes compiler assume things that may not be true 3 */ 4 module ddash.lang.assume; 5 6 /** 7 The assume template takes an alias to a funciton that casts it to a different 8 attribute. 9 10 This can mainly be used for debugging purposes. For example when you want to call a gc 11 function or an unsafe function from nogc or safe code. 12 13 The assume template takes a lambda as a template alias argument and then creates a type that 14 you can call as attributed. e.g. 15 16 --- 17 assume!f1.nogc_(args); // calls f1 with args as if it was nogc 18 assume!f1.pure_(args); // calls f1 with args as if it was pure 19 --- 20 21 Since: 22 - 0.0.1 23 */ 24 template assume(alias fun) { 25 import std.traits: FunctionAttribute, SetFunctionAttributes, functionLinkage, functionAttributes; 26 private auto ref assumeAttribute(FunctionAttribute assumedAttr, T)(auto ref T t) { 27 enum attrs = functionAttributes!T | assumedAttr; 28 return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t; 29 } 30 private static impl(string attr) { 31 return ` 32 enum call = "assumeAttribute!(`~attr~`)((ref Args args) { return fun(args); })(args)"; 33 ` ~ q{ 34 static assert( 35 __traits(compiles, { 36 mixin(call ~ ";"); 37 }), 38 "function " ~ fun.stringof ~ " is not callable with args " ~ Args.stringof 39 ); 40 alias R = typeof(mixin(call)); 41 static if (is(R == void)) { 42 mixin(call ~ ";"); 43 } else { 44 mixin("return " ~ call ~ ";"); 45 } 46 }; 47 } 48 auto ref nogc_(Args...)(auto ref Args args) { 49 mixin(impl("FunctionAttribute.nogc")); 50 } 51 auto ref pure_(Args...)(auto ref Args args) { 52 mixin(impl("FunctionAttribute.pure_")); 53 } 54 } 55 56 /// 57 @nogc unittest { 58 static b = [1]; 59 auto allocates() { 60 return [1]; 61 } 62 auto a = assume!allocates.nogc_(); 63 assert(a == b); 64 65 auto something(int a) { 66 allocates; 67 } 68 assume!something.nogc_(3); 69 } 70 71 /// 72 unittest { 73 static int thing = 0; 74 alias lambda = () => thing++; 75 () pure { 76 cast(void)assume!lambda.pure_(); 77 }(); 78 assert(thing == 1); 79 }