1 /** 2 * Copyright: Copyright (c) 2010-2011 Jacob Carlborg. 3 * Authors: Jacob Carlborg 4 * Version: Initial created: Jan 26, 2010 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 6 */ 7 module mambo.util.Traits; 8 9 import Tango = tango.core.Traits; 10 import Phobos = std.traits; 11 12 import mambo.core..string; 13 14 /// 15 alias Tango.BaseTypeTupleOf BaseTypeTupleOf; 16 17 /// 18 alias Tango.ParameterTupleOf ParameterTupleOf; 19 20 /// 21 alias Tango.ReturnTypeOf ReturnTypeOf; 22 23 /// Evaluates to true if $(D_PARAM T) is a primitive type. 24 template isPrimitive (T) 25 { 26 enum bool isPrimitive = is(T == bool) || 27 is(T == byte) || 28 is(T == cdouble) || 29 //is(T == cent) || 30 is(T == cfloat) || 31 is(T == char) || 32 is(T == creal) || 33 is(T == dchar) || 34 is(T == double) || 35 is(T == float) || 36 is(T == idouble) || 37 is(T == ifloat) || 38 is(T == int) || 39 is(T == ireal) || 40 is(T == long) || 41 is(T == real) || 42 is(T == short) || 43 is(T == ubyte) || 44 //is(T == ucent) || 45 is(T == uint) || 46 is(T == ulong) || 47 is(T == ushort) || 48 is(T == wchar); 49 } 50 51 /// Evaluates to true if $(D_PARAM T) is a character type. 52 template isChar (T) 53 { 54 enum bool isChar = is(T == char) || 55 is(T == wchar) || 56 is(T == dchar) || 57 is(T == immutable(char)) || 58 is(T == immutable(wchar)) || 59 is(T == immutable(dchar)); 60 } 61 62 /// Evaluates to true if $(D_PARAM T) is a floating point type. 63 template isFloatingPoint (T) 64 { 65 enum bool isFloatingPoint = is(T == float) || is(T == double) || is(T == real) || 66 is(T == cfloat) || is(T == cdouble) || is(T == creal) || 67 is(T == ifloat) || is(T == idouble) || is(T == ireal); 68 } 69 70 /// Evaluates to true if $(D_PARAM T) is class. 71 template isClass (T) 72 { 73 enum bool isClass = is(T == class); 74 } 75 76 /// Evaluates to true if $(D_PARAM T) is an interface. 77 template isInterface (T) 78 { 79 enum bool isInterface = is(T == interface); 80 } 81 82 /// Evaluates to true if $(D_PARAM T) is a class or an interface. 83 template isObject (T) 84 { 85 enum bool isObject = isClass!(T) || isInterface!(T); 86 } 87 88 /// Evaluates to true if $(D_PARAM T) is a struct. 89 template isStruct (T) 90 { 91 enum bool isStruct = is(T == struct); 92 } 93 94 /// Evaluates to true if $(D_PARAM T) is a union. 95 template isUnion (T) 96 { 97 enum bool isUnion = is(T == union); 98 } 99 100 /// Evaluates to true if $(D_PARAM T) is an array. 101 template isArray (T) 102 { 103 static if (is(T U : U[])) 104 enum bool isArray = true; 105 106 else 107 enum bool isArray = false; 108 } 109 110 /// Evaluates to true if $(D_PARAM T) is a string. 111 template isString (T) 112 { 113 enum bool isString = is(T : string) || is(T : wstring) || is(T : dstring); 114 } 115 116 /// Evaluates to true if $(D_PARAM T) is a an associative array. 117 template isAssociativeArray (T) 118 { 119 enum bool isAssociativeArray = is(typeof(T.init.values[0])[typeof(T.init.keys[0])] == T) || 120 is(AssociativeArray!(typeof(T.init.keys[0]), typeof(T.init.values[0]))); 121 } 122 123 /// Evaluates to true if $(D_PARAM T) is a pointer. 124 template isPointer (T) 125 { 126 static if (is(T U : U*)) 127 enum bool isPointer = true; 128 129 else 130 enum bool isPointer = false; 131 } 132 133 /// Evaluates to true if $(D_PARAM T) is a function pointer. 134 template isFunctionPointer (T) 135 { 136 enum bool isFunctionPointer = is(typeof(*T) == function); 137 } 138 139 /// Evaluates to true if $(D_PARAM T) is an enum. 140 template isEnum (T) 141 { 142 enum bool isEnum = is(T == enum); 143 } 144 145 /// Evaluates to true if $(D_PARAM T) is an object or a pointer. 146 template isReference (T) 147 { 148 enum bool isReference = isObject!(T) || isPointer!(T); 149 } 150 151 /// Evaluates to true if $(D_PARAM T) is a typedef. 152 template isTypedef (T) 153 { 154 enum bool isTypedef = is(T == typedef); 155 } 156 157 /// Evaluates to true if $(D_PARAM T) is void. 158 template isVoid (T) 159 { 160 enum bool isVoid = is(T == void); 161 } 162 163 /// Evaluates the type of the element of the array. 164 template ElementTypeOfArray(T : T[]) 165 { 166 alias T ElementTypeOfArray; 167 } 168 169 /// Evaluates to the type the pointer points to. 170 template BaseTypeOfPointer (T) 171 { 172 static if (is(T U : U*)) 173 alias BaseTypeOfPointer!(U) BaseTypeOfPointer; 174 175 else 176 alias T BaseTypeOfPointer; 177 } 178 179 /// Evaluates to the base type of the typedef. 180 template BaseTypeOfTypedef (T) 181 { 182 static if (is(T U == typedef)) 183 alias BaseTypeOfTypedef!(U) BaseTypeOfTypedef; 184 185 else 186 alias T BaseTypeOfTypedef; 187 } 188 189 /// Evaluates to the base type of the enum. 190 template BaseTypeOfEnum (T) 191 { 192 static if (is(T U == enum)) 193 alias BaseTypeOfEnum!(U) BaseTypeOfEnum; 194 195 else 196 alias T BaseTypeOfEnum; 197 } 198 199 /// Evaluates to the key type of the associative array. 200 template KeyTypeOfAssociativeArray (T) 201 { 202 static assert(isAssociativeArray!(T), "The type needs to be an associative array"); 203 alias typeof(T.init.keys[0]) KeyTypeOfAssociativeArray; 204 } 205 206 /// Evaluates to the value type of the associative array. 207 template ValueTypeOfAssociativeArray (T) 208 { 209 static assert(isAssociativeArray!(T), "The type needs to be an associative array"); 210 alias typeof(T.init.values[0]) ValueTypeOfAssociativeArray; 211 } 212 213 template isPredicate (alias predicate, Args...) 214 { 215 enum isPredicate = __traits(compiles, { 216 bool r = predicate(Args.init); 217 }); 218 } 219 220 template isAssociativeArrayPredicate (alias predicate, T) 221 { 222 enum isAssociativeArrayPredicate = isPredicate!(predicate, 223 KeyTypeOfAssociativeArray!(T), 224 ValueTypeOfAssociativeArray!(T)); 225 } 226 227 /// Unqualifies the given type, i.e. removing const, immutable and so on. 228 alias Phobos.Unqual Unqual; 229 230 /// Evaluates to true if the given symbol is a type. 231 template isType (alias symbol) 232 { 233 enum isType = __traits(compiles, expectType!(symbol)); 234 } 235 236 private template expectType (T) {} 237 238 /** 239 * Evaluates to the type of the given expression or type. The built-in $(D_KEYWORD typeof) 240 * only accepts expressions, not types. If given a type, this will just evaluate to the given 241 * type as is. 242 */ 243 template TypeOf (alias expr) 244 { 245 static if (isType!(expr)) 246 alias expr TypeOf; 247 248 else 249 alias typeof(expr) TypeOf; 250 } 251 252 /// Evaluates to true if the given argument is a symbol. 253 template isSymbol (alias arg) 254 { 255 enum isSymbol = __traits(compiles, __traits(getAttributes, arg)); 256 }