1 /// 2 module drmi.core.helpers; 3 4 package template rmiFunctionName(alias func) 5 { 6 string impl() 7 { 8 import std.meta : staticMap; 9 import std.traits : Parameters; 10 import std..string : join; 11 import std.algorithm : canFind; 12 13 checkFunction!func; 14 15 template s4t(X) { enum s4t = X.stringof; } 16 17 static if (Parameters!func.length) 18 return __traits(identifier, func) ~ "(" ~ [staticMap!(s4t, Parameters!func)].join(",") ~ ")"; 19 else 20 return __traits(identifier, func) ~ "()"; 21 } 22 enum rmiFunctionName = impl(); 23 } 24 25 package void checkFunction(alias func)() 26 { 27 import std.algorithm : find; 28 import std.traits : hasFunctionAttributes; 29 enum funcstr = __traits(identifier, __traits(parent, __traits(parent, func))) ~ ":" ~ 30 __traits(identifier, __traits(parent, func)) 31 ~ "." ~ __traits(identifier, func); 32 static assert(!hasFunctionAttributes!(func, "@safe"), "@safe not allowed: " ~ funcstr); 33 static assert(!hasFunctionAttributes!(func, "pure"), "pure not allowed: " ~ funcstr); 34 static assert(!hasFunctionAttributes!(func, "@nogc"), "@nogc not allowed: " ~ funcstr); 35 } 36 37 unittest 38 { 39 static auto i = [0]; 40 void foo(int a, double b, string c) @system { i ~= 1; } 41 static assert(rmiFunctionName!foo == "foo(int,double,string)"); 42 void bar() @system { i ~= 2; } 43 static assert(rmiFunctionName!bar == "bar()"); 44 }