Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 2890c13

Browse files
committed
rt.util.typeinfo: Use complex aliases instead of built-in complex types
1 parent 1347f5f commit 2890c13

File tree

2 files changed

+159
-31
lines changed

2 files changed

+159
-31
lines changed

src/core/stdc/config.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ version (StdDdoc)
3131
alias ddoc_long = int;
3232
alias ddoc_ulong = uint;
3333
}
34-
struct ddoc_complex(T) {};
34+
struct ddoc_complex(T) { T re; T im; };
3535
}
3636

3737
/***

src/rt/util/typeinfo.d

Lines changed: 158 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Source: $(DRUNTIMESRC rt/util/_typeinfo.d)
88
*/
99
module rt.util.typeinfo;
10+
import core.stdc.config;
1011
static import core.internal.hash;
1112

1213
template Floating(T)
@@ -36,14 +37,15 @@ if (is(T == float) || is(T == double) || is(T == real))
3637

3738
public alias hashOf = core.internal.hash.hashOf;
3839
}
40+
3941
template Floating(T)
40-
if (is(T == cfloat) || is(T == cdouble) || is(T == creal))
42+
if (is(T == c_complex_float) || is(T == c_complex_double) || is(T == c_complex_real))
4143
{
4244
pure nothrow @safe:
4345

4446
bool equals(T f1, T f2)
4547
{
46-
return f1 == f2;
48+
return f1.re == f2.re && f1.im == f2.im;
4749
}
4850

4951
int compare(T f1, T f2)
@@ -63,12 +65,14 @@ if (is(T == cfloat) || is(T == cdouble) || is(T == creal))
6365
return result;
6466
}
6567

66-
public alias hashOf = core.internal.hash.hashOf;
68+
size_t hashOf(scope const T val)
69+
{
70+
return core.internal.hash.hashOf(val.re, core.internal.hash.hashOf(val.im));
71+
}
6772
}
6873

6974
template Array(T)
70-
if (is(T == float) || is(T == double) || is(T == real) ||
71-
is(T == cfloat) || is(T == cdouble) || is(T == creal))
75+
if (is(T == float) || is(T == double) || is(T == real))
7276
{
7377
pure nothrow @safe:
7478

@@ -105,6 +109,52 @@ if (is(T == float) || is(T == double) || is(T == real) ||
105109
public alias hashOf = core.internal.hash.hashOf;
106110
}
107111

112+
template Array(T)
113+
if (is(T == c_complex_float) || is(T == c_complex_double) || is(T == c_complex_real))
114+
{
115+
pure nothrow @safe:
116+
117+
bool equals(T[] s1, T[] s2)
118+
{
119+
size_t len = s1.length;
120+
if (len != s2.length)
121+
return false;
122+
for (size_t u = 0; u < len; u++)
123+
{
124+
if (!Floating!T.equals(s1[u], s2[u]))
125+
return false;
126+
}
127+
return true;
128+
}
129+
130+
int compare(T[] s1, T[] s2)
131+
{
132+
size_t len = s1.length;
133+
if (s2.length < len)
134+
len = s2.length;
135+
for (size_t u = 0; u < len; u++)
136+
{
137+
if (int c = Floating!T.compare(s1[u], s2[u]))
138+
return c;
139+
}
140+
if (s1.length < s2.length)
141+
return -1;
142+
else if (s1.length > s2.length)
143+
return 1;
144+
return 0;
145+
}
146+
147+
size_t hashOf(scope const T[] val)
148+
{
149+
size_t hash = 0;
150+
foreach (ref o; val)
151+
{
152+
hash = core.internal.hash.hashOf(Floating!T.hashOf(o), hash);
153+
}
154+
return hash;
155+
}
156+
}
157+
108158
version (CoreUnittest)
109159
{
110160
alias TypeTuple(T...) = T;
@@ -177,7 +227,7 @@ TypeInfo information for built-in types.
177227
178228
A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
179229
equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example:
180-
`float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
230+
`char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
181231
the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
182232
during compilation whether they have different signedness and override appropriately. For initializer, we
183233
detect if we need to override. The overriding initializer should be nonzero.
@@ -194,7 +244,10 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
194244
static if (is(T == Base))
195245
override size_t getHash(scope const void* p)
196246
{
197-
static if (__traits(isFloating, T))
247+
static if (__traits(isFloating, T) ||
248+
is(T == c_complex_float) ||
249+
is(T == c_complex_double) ||
250+
is(T == c_complex_real))
198251
return Floating!T.hashOf(*cast(T*)p);
199252
else
200253
return hashOf(*cast(const T *)p);
@@ -204,7 +257,10 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
204257
static if (is(T == Base))
205258
override bool equals(in void* p1, in void* p2)
206259
{
207-
static if (__traits(isFloating, T))
260+
static if (__traits(isFloating, T) ||
261+
is(T == c_complex_float) ||
262+
is(T == c_complex_double) ||
263+
is(T == c_complex_real))
208264
return Floating!T.equals(*cast(T*)p1, *cast(T*)p2);
209265
else
210266
return *cast(T *)p1 == *cast(T *)p2;
@@ -214,7 +270,10 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
214270
static if (is(T == Base) || (__traits(isIntegral, T) && T.max != Base.max))
215271
override int compare(in void* p1, in void* p2)
216272
{
217-
static if (__traits(isFloating, T))
273+
static if (__traits(isFloating, T) ||
274+
is(T == c_complex_float) ||
275+
is(T == c_complex_double) ||
276+
is(T == c_complex_real))
218277
{
219278
return Floating!T.compare(*cast(T*)p1, *cast(T*)p2);
220279
}
@@ -273,9 +332,12 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
273332
}
274333

275334
static if (is(T == Base))
276-
static if (__traits(isFloating, T) && T.mant_dig != 64)
335+
{
336+
static if ((__traits(isFloating, T) && T.mant_dig != 64) ||
337+
is(T == c_complex_float) || is(T == c_complex_double))
277338
// FP types except 80-bit X87 are passed in SIMD register.
278339
override @property uint flags() const { return 2; }
340+
}
279341
}
280342

281343
unittest
@@ -312,7 +374,7 @@ TypeInfo information for arrays of built-in types.
312374
313375
A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
314376
equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example:
315-
`float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
377+
`char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
316378
the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
317379
during compilation whether they have different signedness and override appropriately. For initializer, we
318380
detect if we need to override. The overriding initializer should be nonzero.
@@ -327,7 +389,10 @@ private class TypeInfoArrayGeneric(T, Base = T) : Select!(is(T == Base), TypeInf
327389
static if (is(T == Base))
328390
override size_t getHash(scope const void* p) @trusted const
329391
{
330-
static if (__traits(isFloating, T))
392+
static if (__traits(isFloating, T) ||
393+
is(T == c_complex_float) ||
394+
is(T == c_complex_double) ||
395+
is(T == c_complex_real))
331396
return Array!T.hashOf(*cast(T[]*)p);
332397
else
333398
return hashOf(*cast(const T[]*) p);
@@ -336,7 +401,10 @@ private class TypeInfoArrayGeneric(T, Base = T) : Select!(is(T == Base), TypeInf
336401
static if (is(T == Base))
337402
override bool equals(in void* p1, in void* p2) const
338403
{
339-
static if (__traits(isFloating, T))
404+
static if (__traits(isFloating, T) ||
405+
is(T == c_complex_float) ||
406+
is(T == c_complex_double) ||
407+
is(T == c_complex_real))
340408
{
341409
return Array!T.equals(*cast(T[]*)p1, *cast(T[]*)p2);
342410
}
@@ -353,7 +421,10 @@ private class TypeInfoArrayGeneric(T, Base = T) : Select!(is(T == Base), TypeInf
353421
static if (is(T == Base) || (__traits(isIntegral, T) && T.max != Base.max))
354422
override int compare(in void* p1, in void* p2) const
355423
{
356-
static if (__traits(isFloating, T))
424+
static if (__traits(isFloating, T) ||
425+
is(T == c_complex_float) ||
426+
is(T == c_complex_double) ||
427+
is(T == c_complex_real))
357428
{
358429
return Array!T.compare(*cast(T[]*)p1, *cast(T[]*)p2);
359430
}
@@ -443,17 +514,36 @@ static if (is(ucent)) class TypeInfo_zk : TypeInfoGeneric!ucent {}
443514

444515
// All simple floating-point types.
445516
class TypeInfo_f : TypeInfoGeneric!float {}
446-
class TypeInfo_o : TypeInfoGeneric!(ifloat, float) {}
447517
class TypeInfo_d : TypeInfoGeneric!double {}
448-
class TypeInfo_p : TypeInfoGeneric!(idouble, double) {}
449518
class TypeInfo_e : TypeInfoGeneric!real {}
450-
class TypeInfo_j : TypeInfoGeneric!(ireal, real) {}
519+
520+
// All imaginary floating-point types.
521+
522+
// ifloat @@@DEPRECATED_2.105@@@
523+
deprecated class TypeInfo_o : TypeInfoGeneric!float
524+
{
525+
override string toString() const pure nothrow @safe { return "ifloat"; }
526+
}
527+
528+
// idouble @@@DEPRECATED_2.105@@@
529+
deprecated class TypeInfo_p : TypeInfoGeneric!double
530+
{
531+
override string toString() const pure nothrow @safe { return "idouble"; }
532+
}
533+
534+
// ireal @@@DEPRECATED_2.105@@@
535+
deprecated class TypeInfo_j : TypeInfoGeneric!real
536+
{
537+
override string toString() const pure nothrow @safe { return "ireal"; }
538+
}
451539

452540
// All complex floating-point types.
453541

454-
// cfloat
455-
class TypeInfo_q : TypeInfoGeneric!cfloat
542+
// cfloat @@@DEPRECATED_2.105@@@
543+
deprecated class TypeInfo_q : TypeInfoGeneric!c_complex_float
456544
{
545+
override string toString() const pure nothrow @safe { return "cfloat"; }
546+
457547
const: nothrow: pure: @trusted:
458548
static if (__traits(hasMember, TypeInfo, "argTypes"))
459549
override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
@@ -463,9 +553,11 @@ class TypeInfo_q : TypeInfoGeneric!cfloat
463553
}
464554
}
465555

466-
// cdouble
467-
class TypeInfo_r : TypeInfoGeneric!cdouble
556+
// cdouble @@@DEPRECATED_2.105@@@
557+
deprecated class TypeInfo_r : TypeInfoGeneric!c_complex_double
468558
{
559+
override string toString() const pure nothrow @safe { return "cdouble"; }
560+
469561
const: nothrow: pure: @trusted:
470562
static if (__traits(hasMember, TypeInfo, "argTypes"))
471563
override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
@@ -476,9 +568,11 @@ class TypeInfo_r : TypeInfoGeneric!cdouble
476568
}
477569
}
478570

479-
// creal
480-
class TypeInfo_c : TypeInfoGeneric!creal
571+
// creal @@@DEPRECATED_2.105@@@
572+
deprecated class TypeInfo_c : TypeInfoGeneric!c_complex_real
481573
{
574+
override string toString() const pure nothrow @safe { return "creal"; }
575+
482576
const: nothrow: pure: @trusted:
483577
static if (__traits(hasMember, TypeInfo, "argTypes"))
484578
override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
@@ -548,16 +642,50 @@ unittest
548642
assert(!(a1 < b1 && b1 < a1)); // Original failing case
549643
}
550644

551-
// Arrays of all floating point types.
645+
// Arrays of all simple floating-point types.
552646
class TypeInfo_Af : TypeInfoArrayGeneric!float {}
553-
class TypeInfo_Ao : TypeInfoArrayGeneric!(ifloat, float) {}
554647
class TypeInfo_Ad : TypeInfoArrayGeneric!double {}
555-
class TypeInfo_Ap : TypeInfoArrayGeneric!(idouble, double) {}
556648
class TypeInfo_Ae : TypeInfoArrayGeneric!real {}
557-
class TypeInfo_Aj : TypeInfoArrayGeneric!(ireal, real) {}
558-
class TypeInfo_Aq : TypeInfoArrayGeneric!cfloat {}
559-
class TypeInfo_Ar : TypeInfoArrayGeneric!cdouble {}
560-
class TypeInfo_Ac : TypeInfoArrayGeneric!creal {}
649+
650+
// Arrays of all imaginary floating-point types.
651+
652+
// ifloat @@@DEPRECATED_2.105@@@
653+
deprecated class TypeInfo_Ao : TypeInfoArrayGeneric!float
654+
{
655+
override string toString() const pure nothrow @safe { return "ifloat[]"; }
656+
}
657+
658+
// idouble @@@DEPRECATED_2.105@@@
659+
deprecated class TypeInfo_Ap : TypeInfoArrayGeneric!double
660+
{
661+
override string toString() const pure nothrow @safe { return "idouble[]"; }
662+
}
663+
664+
// ireal @@@DEPRECATED_2.105@@@
665+
deprecated class TypeInfo_Aj : TypeInfoArrayGeneric!real
666+
{
667+
override string toString() const pure nothrow @safe { return "ireal[]"; }
668+
}
669+
670+
// Arrays of all complex floating-point types.
671+
672+
// cfloat @@@DEPRECATED_2.105@@@
673+
deprecated class TypeInfo_Aq : TypeInfoArrayGeneric!c_complex_float
674+
{
675+
override string toString() const pure nothrow @safe { return "cfloat[]"; }
676+
}
677+
678+
// cdouble @@@DEPRECATED_2.105@@@
679+
deprecated class TypeInfo_Ar : TypeInfoArrayGeneric!c_complex_double
680+
{
681+
override string toString() const pure nothrow @safe { return "cdouble[]"; }
682+
}
683+
684+
// creal @@@DEPRECATED_2.105@@@
685+
deprecated class TypeInfo_Ac : TypeInfoArrayGeneric!c_complex_real
686+
{
687+
override string toString() const pure nothrow @safe { return "creal[]"; }
688+
}
561689

562690
// void[] is a bit different, behaves like ubyte[] for comparison purposes.
563691
class TypeInfo_Av : TypeInfo_Ah

0 commit comments

Comments
 (0)