1 /// Extension of std.traist used in the tagion project 2 module tagion.basic.traits; 3 import std.meta : ApplyRight, Filter, staticMap; 4 import std.range.primitives : isInputRange; 5 import std.traits : getUDAs, hasUDA; 6 7 /** 8 Similar to .stringof but working on member functions 9 Params: 10 member = symbol of module,struct or class 11 Returns: the name of the symbol 12 */ 13 template getName(alias member) { 14 import std.algorithm.iteration : splitter; 15 import std.range : tail; 16 import std.traits : fullyQualifiedName; 17 18 enum getName = fullyQualifiedName!(member).splitter('.').tail(1).front; 19 } 20 21 /** 22 Params: 23 member = symbol of a member 24 Returns: 25 all overloads of the member 26 */ 27 template getOverloads(alias member) { 28 alias Parent = __traits(parent, member); 29 alias getOverloads = __traits(getOverloads, Parent, getName!member); 30 } 31 32 /** 33 * Params: 34 * member = symbol of a member 35 * UDA = User defined attribute of the member 36 * Returns: 37 * all the member symbols which has this UDA 38 * If no UDA was found a empty alias sequency will be returned 39 */ 40 template hasMemberUDA(alias member, alias UDA) { 41 alias Overloads = getOverloads!(member); 42 alias hasTheUDA = ApplyRight!(hasUDA, UDA); 43 alias hasMemberUDA = Filter!(hasTheUDA, Overloads); 44 } 45 46 enum hasOneMemberUDA(alias member, alias UDA) = hasMemberUDA!(member, UDA).length is 1; 47 48 /** 49 * Params: 50 * member = symbol of a member 51 * UDA = User defined attribute of the member 52 * Returns: 53 * 54 */ 55 template getMemberUDAs(alias member, alias UDA) { 56 alias Overloads = getOverloads!(member); 57 alias getTheUDAs = ApplyRight!(getUDAs, UDA); 58 alias getMemberUDAs = staticMap!(getTheUDAs, hasMemberUDA!(member, UDA)); 59 } 60 61 /// 62 static unittest { 63 import std.typecons : Tuple; 64 65 enum test; 66 struct special { 67 string label; 68 } 69 70 struct S { 71 @test 72 int func() { 73 return 0; 74 } 75 76 @special("text") 77 int func(int x) { 78 return x; 79 } 80 81 string func(string str) { 82 return str; 83 } 84 } 85 86 static assert(getName!(S.func) == "func"); 87 static assert(__traits(isSame, __traits(getOverloads, S, "func"), getOverloads!(S.func))); 88 /// UDA @test 89 static assert(hasMemberUDA!(S.func, test).length is 1); 90 static assert(__traits(isSame, hasMemberUDA!(S.func, test)[0], getOverloads!(S.func)[0])); 91 static assert(is(getMemberUDAs!(S.func, test)[0] == test)); 92 /// UDA special 93 static assert(hasMemberUDA!(S.func, special).length is 1); 94 static assert(__traits(isSame, hasMemberUDA!(S.func, special)[0], getOverloads!(S.func)[1])); 95 enum s_special = getMemberUDAs!(S.func, special)[0]; 96 static assert(s_special == special("text")); 97 }