The OpenD Programming Language

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; });