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 mambo.core.Attribute;
8 
9 import tango.core.Tuple;
10 import std.typetuple : Filter;
11 
12 import mambo.util.Traits;
13 
14 /**
15  * This s represent a meta attribute. Any declaration that has this attribute attached to
16  * itself is to be considered an attribute. That declaration should only be used as an
17  * attribute and never on its own.
18  */
19 struct attribute { }
20 
21 /**
22  * Evaluates to true if the given symbol is an attribute. An attribute is any declaration with
23  * the "mambo.core.Attribute.attribute" attribute attached.
24  */
25 template isAttribute (alias symbol)
26 {
27 	static if (isSymbol!(symbol))
28 		enum isAttribute = getAttributes!(symbol, true).contains!(attribute);
29 
30 	else
31 		enum isAttribute = false;
32 }
33 
34 /**
35  * Returns a tuple of all attributes attached to the given symbol. By default this will only
36  * include actual attributes (see mambo.core.Attribute.isAttribute).
37  *
38  * Params:
39  *     symbol = the symbol to return the attributes for
40  *     includeNonAttributes = if true, will return all values. Included those not considered
41  * 							   attributes
42  */
43 template getAttributes (alias symbol, bool includeNonAttributes = false)
44 {
45 	alias Tuple!(__traits(getAttributes, symbol)) Attrs;
46 
47 	static if (includeNonAttributes)
48 		alias Attrs FilteredAttrs;
49 
50 	else
51 		alias Filter!(isAttribute, Attrs) FilteredAttrs;
52 
53 	alias Attributes!(symbol, FilteredAttrs) getAttributes;
54 }
55 
56 /// This struct represent a tuple of attributes attached to the symbol.
57 struct Attributes (alias sym, Attrs ...)
58 {
59 
60 static:
61 
62 	/// The symbol these attributes originated from
63 	alias sym symbol;
64 
65 	/// Returns true if these attributes contain the given symbol
66 	bool contains (alias symbol) ()
67 	{
68 		return any ? IndexOf!(symbol, Attrs) != -1 : false;
69 	}
70 
71 	/// Returns true if the attributes are empty.
72 	bool isEmpty ()
73 	{
74 		return length == 0;
75 	}
76 
77 	/// Returns the length of the attributes.
78 	size_t length ()
79 	{
80 		return Attrs.length;
81 	}
82 
83 	/// Returns true if there are any attributes.
84 	bool any ()
85 	{
86 		return !isEmpty;
87 	}
88 }