1 /// 2 module dpq.meta; 3 4 import dpq.attributes; 5 6 import std.traits; 7 import std.typecons : Nullable; 8 import std.datetime : SysTime; 9 10 version(unittest) import std.stdio; 11 12 /** 13 Returns the array's base type 14 15 Returns the string type for any type that returns true 16 for isSomeString!T 17 18 Examples: 19 --------------- 20 alias T = BaseType!(int[][]); 21 alias T2 = BaseType!(int[]); 22 alias T3 = BaseType!int; 23 alias T4 = BaseType!(string[]) 24 25 static assert(is(T == int)); 26 static assert(is(T2 == int)); 27 static assert(is(T3 == int)); 28 static assert(is(T4 == string)); 29 --------------- 30 */ 31 template BaseType(T) 32 { 33 import std.typecons : TypedefType; 34 static if (isArray!T && !isSomeString!T) 35 alias BaseType = BaseType!(ForeachType!T); 36 else 37 alias BaseType = TypedefType!(Unqual!T); 38 } 39 40 unittest 41 { 42 writeln(" * meta"); 43 writeln("\t * BaseType"); 44 45 static assert(is(BaseType!(int[][][]) == int)); 46 static assert(is(BaseType!(string[]) == string)); 47 static assert(is(BaseType!string == string)); 48 static assert(is(BaseType!dstring == dstring)); 49 } 50 51 /** 52 Returns the number of dimensions of the given array type 53 54 Examples: 55 ----------------- 56 auto dims = ArrayDimensions!(int[][]); 57 static assert(dims == 2); 58 ----------------- 59 */ 60 deprecated("Use ArraySerialier's ArrayDimensions instead") 61 template ArrayDimensions(T) 62 { 63 static if (isArray!T) 64 enum ArrayDimensions = 1 + ArrayDimensions!(ForeachType!T); 65 else 66 enum ArrayDimensions = 0; 67 } 68 69 70 /// Removes any Nullable specifiers, even multiple levels 71 template NoNullable(T) 72 { 73 static if (isInstanceOf!(Nullable, T)) 74 // Nullable nullable? Costs us nothing, so why not 75 alias NoNullable = NoNullable!(Unqual!(ReturnType!(T.get))); 76 else 77 alias NoNullable = T; 78 } 79 80 /** 81 Will strip off any Nullable, Typedefs and qualifiers from a given type. 82 It's a bit paranoid and tries to remove any identifiers multiple times, until 83 the removal attempt yields no changes, but it shouldn't be a problem since it's 84 all just compile-time. 85 86 Examples: 87 static assert(RealType!(const Nullable!(immutable int) == int)); 88 */ 89 template RealType(T) 90 { 91 import std.typecons : TypedefType; 92 // Ugly, but better than doing this every time we need it 93 alias NT = OriginalType!(Unqual!(NoNullable!(TypedefType!T))); 94 95 static if (is(T == NT)) 96 alias RealType = NT; 97 else 98 alias RealType = RealType!NT; 99 }