1 /// 2 module mir.internal.utility; 3 4 private alias AliasSeq(T...) = T; 5 6 /// 7 alias Iota(size_t j) = Iota!(0, j); 8 9 /// 10 template Iota(size_t i, size_t j) 11 { 12 static assert(i <= j, "Iota: i should be less than or equal to j"); 13 static if (i == j) 14 alias Iota = AliasSeq!(); 15 else 16 alias Iota = AliasSeq!(i, Iota!(i + 1, j)); 17 } 18 19 /// 20 template realType(C) 21 if (__traits(isFloating, C) || isComplex!C) 22 { 23 import std.traits: Unqual; 24 static if (isComplex!C) 25 alias realType = typeof(Unqual!C.init.re); 26 else 27 alias realType = Unqual!C; 28 } 29 30 /// 31 template isComplex(C) 32 { 33 static if (is(C == struct) || is(C == enum)) 34 { 35 static if (hasField!(C, "re") && hasField!(C, "im") && C.init.tupleof.length == 2) 36 enum isComplex = isFloatingPoint!(typeof(C.init.tupleof[0])); 37 else 38 enum isComplex = false; 39 } 40 else 41 { 42 // for backward compatability with cfloat, cdouble and creal 43 enum isComplex = __traits(isFloating, C) && !isFloatingPoint!C && !is(C : __vector(F[N]), F, size_t N); 44 } 45 } 46 47 version(LDC) 48 version(mir_core_test) 49 unittest 50 { 51 static assert(!isComplex!(__vector(double[2]))); 52 } 53 54 /// 55 template isComplexOf(C, F) 56 if (isFloatingPoint!F) 57 { 58 static if (isComplex!C) 59 enum isComplexOf = is(typeof(C.init.re) == F); 60 else 61 enum isComplexOf = false; 62 } 63 64 /// 65 template isFloatingPoint(C) 66 { 67 import std.traits: Unqual; 68 alias U = Unqual!C; 69 enum isFloatingPoint = is(U == double) || is(U == float) || is(U == real); 70 } 71 72 // copy to reduce imports 73 enum bool hasField(T, string member) = __traits(compiles, (ref T aggregate) { return __traits(getMember, aggregate, member).offsetof; });