1 
2 module dquery.attribute;
3 
4 import std.typetuple;
5 
6 struct DQueryAttribute(alias Attribute)
7 {
8 
9 	/++
10 	 + Property that returns the value of the attribute.
11 	 ++/
12 	@property
13 	alias attribute = Attribute;
14 
15 	/++
16 	 + Property that returns the value of the attribute.
17 	 ++/
18 	@property
19 	alias get = Attribute;
20 
21 	/++
22 	 + Proprety that returns true if the attribute is a type.
23 	 ++/
24 	@property
25 	alias isType = Alias!(
26 		!is(typeof(Attribute))
27 	);
28 
29 	/++
30 	 + Property that returns true if the attribute is an expression.
31 	 ++/
32 	@property
33 	alias isExpression = Alias!(
34 		is(typeof(Attribute))
35 	);
36 
37 	// Determine how to get the type.
38 	static if(isExpression)
39 	{
40 		/++
41 		 + Property that returns the type of the attribute.
42 		 ++/
43 		@property
44 		alias type = typeof(Attribute);
45 
46 		/++
47 		 + Property that return the value of the attributes.
48 		 + Only defined for attributes that can produce a value.
49 		 ++/
50 		@property
51 		alias value = Attribute;
52 
53 		/++
54 		 + Property that returns the value of the attribute, or a default.
55 		 ++/
56 		@property
57 		alias valueOr(alias Default) = Attribute;
58 	}
59 	else
60 	{
61 		/++
62 		 + Property that returns the type of the attribute.
63 		 ++/
64 		@property
65 		alias type = Attribute;
66 
67 		/++
68 		 + Property that returns the value of the attribute, or a default.
69 		 ++/
70 		@property
71 		alias valueOr(alias Default) = Default;
72 	}
73 
74 	/++
75 	 + Property that returns true if a given type matches the attribute's
76 	 + type exactly.
77 	 ++/
78 	@property
79 	alias isTypeOf(Type) = Alias!(
80 		is(type == Type)
81 	);
82 
83 	/++
84 	 + Property that returns true if a given type can be assigned to a
85 	 + variable of the attribute's type.
86 	 ++/
87 	@property
88 	alias isTypeAssignableTo(Type) = Alias!(
89 		__traits(compiles, {
90 			type t1 = void;
91 			Type t2 = t1;
92 		})
93 	);
94 
95 	/++
96 	 + Property that returns true if a given type can be assigned from a
97 	 + variable of the attribute's type.
98 	 ++/
99 	@property
100 	alias isTypeAssignableFrom(Type) = Alias!(
101 		__traits(compiles, {
102 			Type t1 = void;
103 			type t2 = t1;
104 		})
105 	);
106 
107 	@property
108 	static auto opCall()
109 	{
110 		DQueryAttribute!(Attribute) attribute = void;
111 		return attribute;
112 	}
113 
114 	@property
115 	static auto query()()
116 	{
117 		import dquery.d;
118 		return query!type;
119 	}
120 
121 	string toString()
122 	{
123 		return Attribute.stringof;
124 	}
125 
126 }