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 orange.util.Traits; 8 9 import orange.serialization.Serializable; 10 import orange.serialization.archives.Archive; 11 import orange.util._; 12 13 14 import Phobos = std.traits; 15 16 /// 17 alias Phobos.BaseTypeTuple BaseTypeTupleOf; 18 19 /// Evaluates to true if $(D_PARAM T) is a primitive type. 20 template isPrimitive (T) 21 { 22 enum bool isPrimitive = is(T == bool) || 23 is(T == byte) || 24 is(T == cdouble) || 25 //is(T == cent) || 26 is(T == cfloat) || 27 is(T == char) || 28 is(T == creal) || 29 is(T == dchar) || 30 is(T == double) || 31 is(T == float) || 32 is(T == idouble) || 33 is(T == ifloat) || 34 is(T == int) || 35 is(T == ireal) || 36 is(T == long) || 37 is(T == real) || 38 is(T == short) || 39 is(T == ubyte) || 40 //is(T == ucent) || 41 is(T == uint) || 42 is(T == ulong) || 43 is(T == ushort) || 44 is(T == wchar); 45 } 46 47 /// Evaluates to true if $(D_PARAM T) is a floating point type. 48 template isFloatingPoint (T) 49 { 50 enum bool isFloatingPoint = is(T == float) || is(T == double) || is(T == real) || 51 is(T == cfloat) || is(T == cdouble) || is(T == creal) || 52 is(T == ifloat) || is(T == idouble) || is(T == ireal); 53 } 54 55 /// Evaluates to true if $(D_PARAM T) is class. 56 template isClass (T) 57 { 58 enum bool isClass = is(T == class); 59 } 60 61 /// Evaluates to true if $(D_PARAM T) is an interface. 62 template isInterface (T) 63 { 64 enum bool isInterface = is(T == interface); 65 } 66 67 /// Evaluates to true if $(D_PARAM T) is a class or an interface. 68 template isObject (T) 69 { 70 enum bool isObject = isClass!(T) || isInterface!(T); 71 } 72 73 /// Evaluates to true if $(D_PARAM T) is a struct. 74 template isStruct (T) 75 { 76 enum bool isStruct = is(T == struct); 77 } 78 79 /// Evaluates to true if $(D_PARAM T) is an array. 80 template isArray (T) 81 { 82 static if (is(T U : U[])) 83 enum bool isArray = true; 84 85 else 86 enum bool isArray = false; 87 } 88 89 /// Evaluates to true if $(D_PARAM T) is a static array. 90 enum isStaticArray (T) = is(T : U[n], U, size_t n); 91 92 /// Evaluates to true if $(D_PARAM T) is a string. 93 template isString (T) 94 { 95 enum bool isString = is(T : string) || is(T : wstring) || is(T : dstring); 96 } 97 98 /// Evaluates to true if $(D_PARAM T) is a an associative array. 99 template isAssociativeArray (T) 100 { 101 enum bool isAssociativeArray = is(typeof(T.init.values[0])[typeof(T.init.keys[0])] == T); 102 } 103 104 /// Evaluates to true if $(D_PARAM T) is a pointer. 105 template isPointer (T) 106 { 107 static if (is(T U : U*)) 108 enum bool isPointer = true; 109 110 else 111 enum bool isPointer = false; 112 } 113 114 /// Evaluates to true if $(D_PARAM T) is a function pointer. 115 template isFunctionPointer (T) 116 { 117 enum bool isFunctionPointer = is(typeof(*T) == function); 118 } 119 120 /// Evaluates to true if $(D_PARAM T) is an enum. 121 template isEnum (T) 122 { 123 enum bool isEnum = is(T == enum); 124 } 125 126 /// Evaluates to true if $(D_PARAM T) is an object or a pointer. 127 template isReference (T) 128 { 129 enum bool isReference = isObject!(T) || isPointer!(T); 130 } 131 132 /// Evaluates to true if $(D_PARAM T) is void. 133 template isVoid (T) 134 { 135 enum bool isVoid = is(T == void); 136 } 137 138 /// Evaluates the type of the element of the array. 139 template ElementTypeOfArray(T : T[]) 140 { 141 alias T ElementTypeOfArray; 142 } 143 144 /// Evaluates to the type the pointer points to. 145 template BaseTypeOfPointer (T) 146 { 147 static if (is(T U : U*)) 148 alias BaseTypeOfPointer!(U) BaseTypeOfPointer; 149 150 else 151 alias T BaseTypeOfPointer; 152 } 153 154 /// Evaluates to the base type of the enum. 155 template BaseTypeOfEnum (T) 156 { 157 static if (is(T U == enum)) 158 alias BaseTypeOfEnum!(U) BaseTypeOfEnum; 159 160 else 161 alias T BaseTypeOfEnum; 162 } 163 164 /// Evaluates to the key type of the associative array. 165 template KeyTypeOfAssociativeArray (T) 166 { 167 static assert(isAssociativeArray!(Unqual!(T)), "The type needs to be an associative array"); 168 alias typeof(T.init.keys[0]) KeyTypeOfAssociativeArray; 169 } 170 171 /// Evaluates to the value type of the associative array. 172 template ValueTypeOfAssociativeArray (T) 173 { 174 static assert(isAssociativeArray!(Unqual!(T)), "The type needs to be an associative array"); 175 alias typeof(T.init.values[0]) ValueTypeOfAssociativeArray; 176 } 177 178 /// Evaluates to the type of the data type. 179 template TypeOfDataType (T) 180 { 181 alias T.DataType TypeOfDataType; 182 } 183 184 /// Unqualifies the given type, i.e. removing const, immutable and so on. 185 alias Phobos.Unqual Unqual; 186 187 /// Evaluates to true if the given symbol is a type. 188 template isType (alias symbol) 189 { 190 enum isType = __traits(compiles, expectType!(symbol)); 191 } 192 193 private template expectType (T) {} 194 195 /** 196 * Evaluates to the type of the given expression or type. The built-in $(D_KEYWORD typeof) 197 * only accepts expressions, not types. If given a type, this will just evaluate to the given 198 * type as is. 199 */ 200 template TypeOf (alias expr) 201 { 202 static if (isType!(expr)) 203 alias expr TypeOf; 204 205 else 206 alias typeof(expr) TypeOf; 207 } 208 209 /// Evaluates to true if the given argument is a symbol. 210 template isSymbol (alias arg) 211 { 212 enum isSymbol = __traits(compiles, __traits(getAttributes, arg)); 213 }