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 static if (__traits(getAliasThis, C).length == 1) 39 enum isComplex = .isComplex!(typeof(__traits(getMember, C, __traits(getAliasThis, C)[0]))); 40 else 41 enum isComplex = false; 42 } 43 else 44 { 45 // for backward compatability with cfloat, cdouble and creal 46 enum isComplex = __traits(isFloating, C) && !isFloatingPoint!C && !is(C : __vector(F[N]), F, size_t N); 47 } 48 } 49 50 /// 51 version(mir_core_test) 52 unittest 53 { 54 static assert(!isComplex!double); 55 import mir.complex: Complex; 56 static assert(isComplex!(Complex!double)); 57 import std.complex: PhobosComplex = Complex; 58 static assert(isComplex!(PhobosComplex!double)); 59 60 static struct C 61 { 62 Complex!double value; 63 alias value this; 64 } 65 66 static assert(isComplex!C); 67 } 68 69 /// 70 version(LDC) 71 version(mir_core_test) 72 unittest 73 { 74 static assert(!isComplex!(__vector(double[2]))); 75 } 76 77 /// 78 template isComplexOf(C, F) 79 if (isFloatingPoint!F) 80 { 81 static if (isComplex!C) 82 enum isComplexOf = is(typeof(C.init.re) == F); 83 else 84 enum isComplexOf = false; 85 } 86 87 /// 88 template isFloatingPoint(C) 89 { 90 import std.traits: Unqual; 91 alias U = Unqual!C; 92 enum isFloatingPoint = is(U == double) || is(U == float) || is(U == real); 93 } 94 95 // copy to reduce imports 96 enum bool hasField(T, string member) = __traits(compiles, (ref T aggregate) { return __traits(getMember, aggregate, member).offsetof; });