1 module unit_threaded.uda;
2 
3 import std.traits;
4 import std.typetuple;
5 
6 /**
7  * For the given module, return true if this module's member has
8  * the given UDA. UDAs can be types or values.
9  */
10 template HasAttribute(alias module_, string member, alias attribute) {
11     mixin("import " ~ fullyQualifiedName!module_ ~ ";"); //so it's visible
12     enum isAttribute(alias T) = is(TypeOf!T == attribute);
13     alias attrs = Filter!(isAttribute, __traits(getAttributes, mixin(member)));
14 
15     static assert(attrs.length == 0 || attrs.length == 1,
16                   text("Maximum number of attributes is 1 for ", attribute));
17 
18     static if(attrs.length == 0) {
19         enum HasAttribute = false;
20     } else {
21         enum HasAttribute = true;
22     }
23 }
24 
25 /**
26  * For the given module, return true if this module's member has
27  * the given UDA. UDAs can be types or values.
28  */
29 template GetAttributes(alias module_, string member, A) {
30     mixin("import " ~ fullyQualifiedName!module_ ~ ";"); //so it's visible
31     enum isAttribute(alias T) = is(TypeOf!T == A);
32     alias GetAttributes = Filter!(isAttribute, __traits(getAttributes, mixin(member)));
33 }
34 
35 
36 /**
37  * Utility to allow checking UDAs regardless of whether the template
38  * parameter is or has a type
39  */
40 private template TypeOf(alias T) {
41     static if(__traits(compiles, typeof(T))) {
42         alias TypeOf = typeof(T);
43     } else {
44         alias TypeOf = T;
45     }
46 }
47 
48 
49 
50 unittest {
51 
52     import unit_threaded.attrs;
53     import unit_threaded.tests.module_with_attrs;
54 
55     //check for value UDAs
56     static assert(HasAttribute!(unit_threaded.tests.module_with_attrs, "testAttrs", HiddenTest));
57     static assert(HasAttribute!(unit_threaded.tests.module_with_attrs, "testAttrs", ShouldFail));
58     static assert(!HasAttribute!(unit_threaded.tests.module_with_attrs, "testAttrs", Name));
59 
60     //check for non-value UDAs
61     static assert(HasAttribute!(unit_threaded.tests.module_with_attrs, "testAttrs", SingleThreaded));
62     static assert(!HasAttribute!(unit_threaded.tests.module_with_attrs, "testAttrs", DontTest));
63 }