1 /**
2  * Copyright: Copyright (c) 2013 Jacob Carlborg. All rights reserved.
3  * Authors: Jacob Carlborg
4  * Version: Initial created: Jan 5, 2013
5  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6  */
7 module orange.core.Attribute;
8 
9 import std.typetuple;
10 
11 import orange.util.Traits;
12 
13 /**
14  * This struct represent a meta attribute. Any declaration that has this attribute attached to
15  * itself is to be considered an attribute. That declaration should only be used as an
16  * attribute and never on its own.
17  */
18 struct attribute { }
19 
20 /**
21  * Evaluates to true if the given symbol is an attribute. An attribute is any declaration with
22  * the "orange.core.Attribute.attribute" attribute attached.
23  */
24 template isAttribute (alias symbol)
25 {
26     static if (isSymbol!(symbol))
27         enum isAttribute = getAttributes!(symbol, true).contains!(attribute);
28 
29     else
30         enum isAttribute = false;
31 }
32 
33 /**
34  * Returns a tuple of all attributes attached to the given symbol. By default this will only
35  * include actual attributes (see orange.core.Attribute.isAttribute).
36  *
37  * Params:
38  *     symbol = the symbol to return the attributes for
39  *     includeNonAttributes = if true, will return all values. Included those not considered
40  *                                attributes
41  */
42 template getAttributes (alias symbol, bool includeNonAttributes = false)
43 {
44     static if (!__traits(compiles, __traits(getAttributes, symbol)))
45         alias Attributes!(symbol, TypeTuple!()) getAttributes;
46 
47     else
48     {
49         alias TypeTuple!(__traits(getAttributes, symbol)) Attrs;
50 
51         static if (includeNonAttributes)
52             alias Attrs FilteredAttrs;
53 
54         else
55             alias Filter!(isAttribute, Attrs) FilteredAttrs;
56 
57         alias Attributes!(symbol, FilteredAttrs) getAttributes;
58     }
59 }
60 
61 /// This struct represent a tuple of attributes attached to the symbol.
62 struct Attributes (alias sym, Attrs ...)
63 {
64 
65 static:
66 
67     /// The symbol these attributes originated from
68     alias sym symbol;
69 
70     /// Returns true if these attributes contain the given symbol
71     bool contains (alias symbol) ()
72     {
73         return any ? staticIndexOf!(symbol, Attrs) != -1 : false;
74     }
75 
76     /// Returns true if the attributes are empty.
77     bool isEmpty ()
78     {
79         return length == 0;
80     }
81 
82     /// Returns the length of the attributes.
83     size_t length ()
84     {
85         return Attrs.length;
86     }
87 
88     /// Returns true if there are any attributes.
89     bool any ()
90     {
91         return !isEmpty;
92     }
93 }