7
7
* Source: $(DRUNTIMESRC rt/util/_typeinfo.d)
8
8
*/
9
9
module rt.util.typeinfo ;
10
+ import core.stdc.config ;
10
11
static import core.internal.hash ;
11
12
12
13
template Floating (T)
@@ -36,14 +37,15 @@ if (is(T == float) || is(T == double) || is(T == real))
36
37
37
38
public alias hashOf = core.internal.hash.hashOf ;
38
39
}
40
+
39
41
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 ))
41
43
{
42
44
pure nothrow @safe :
43
45
44
46
bool equals (T f1, T f2)
45
47
{
46
- return f1 == f2;
48
+ return f1.re == f2.re && f1.im == f2.im ;
47
49
}
48
50
49
51
int compare (T f1, T f2)
@@ -63,12 +65,14 @@ if (is(T == cfloat) || is(T == cdouble) || is(T == creal))
63
65
return result;
64
66
}
65
67
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
+ }
67
72
}
68
73
69
74
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 ))
72
76
{
73
77
pure nothrow @safe :
74
78
@@ -105,6 +109,52 @@ if (is(T == float) || is(T == double) || is(T == real) ||
105
109
public alias hashOf = core.internal.hash.hashOf ;
106
110
}
107
111
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
+
108
158
version (CoreUnittest)
109
159
{
110
160
alias TypeTuple (T... ) = T;
@@ -177,7 +227,7 @@ TypeInfo information for built-in types.
177
227
178
228
A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
179
229
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
181
231
the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
182
232
during compilation whether they have different signedness and override appropriately. For initializer, we
183
233
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)
194
244
static if (is (T == Base))
195
245
override size_t getHash (scope const void * p)
196
246
{
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))
198
251
return Floating! T.hashOf(* cast (T* )p);
199
252
else
200
253
return hashOf (* cast (const T * )p);
@@ -204,7 +257,10 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
204
257
static if (is (T == Base))
205
258
override bool equals (in void * p1, in void * p2)
206
259
{
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))
208
264
return Floating! T.equals(* cast (T* )p1, * cast (T* )p2);
209
265
else
210
266
return * cast (T * )p1 == * cast (T * )p2;
@@ -214,7 +270,10 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
214
270
static if (is (T == Base) || (__traits(isIntegral, T) && T.max != Base.max))
215
271
override int compare (in void * p1, in void * p2)
216
272
{
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))
218
277
{
219
278
return Floating! T.compare(* cast (T* )p1, * cast (T* )p2);
220
279
}
@@ -273,9 +332,12 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
273
332
}
274
333
275
334
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))
277
338
// FP types except 80-bit X87 are passed in SIMD register.
278
339
override @property uint flags() const { return 2 ; }
340
+ }
279
341
}
280
342
281
343
unittest
@@ -312,7 +374,7 @@ TypeInfo information for arrays of built-in types.
312
374
313
375
A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
314
376
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
316
378
the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
317
379
during compilation whether they have different signedness and override appropriately. For initializer, we
318
380
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
327
389
static if (is (T == Base))
328
390
override size_t getHash (scope const void * p) @trusted const
329
391
{
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))
331
396
return Array! T.hashOf(* cast (T[]* )p);
332
397
else
333
398
return hashOf (* cast (const T[]* ) p);
@@ -336,7 +401,10 @@ private class TypeInfoArrayGeneric(T, Base = T) : Select!(is(T == Base), TypeInf
336
401
static if (is (T == Base))
337
402
override bool equals (in void * p1, in void * p2) const
338
403
{
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))
340
408
{
341
409
return Array! T.equals(* cast (T[]* )p1, * cast (T[]* )p2);
342
410
}
@@ -353,7 +421,10 @@ private class TypeInfoArrayGeneric(T, Base = T) : Select!(is(T == Base), TypeInf
353
421
static if (is (T == Base) || (__traits(isIntegral, T) && T.max != Base.max))
354
422
override int compare (in void * p1, in void * p2) const
355
423
{
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))
357
428
{
358
429
return Array! T.compare(* cast (T[]* )p1, * cast (T[]* )p2);
359
430
}
@@ -443,17 +514,36 @@ static if (is(ucent)) class TypeInfo_zk : TypeInfoGeneric!ucent {}
443
514
444
515
// All simple floating-point types.
445
516
class TypeInfo_f : TypeInfoGeneric !float {}
446
- class TypeInfo_o : TypeInfoGeneric !(ifloat, float) {}
447
517
class TypeInfo_d : TypeInfoGeneric !double {}
448
- class TypeInfo_p : TypeInfoGeneric !(idouble, double) {}
449
518
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
+ }
451
539
452
540
// All complex floating-point types.
453
541
454
- // cfloat
455
- class TypeInfo_q : TypeInfoGeneric !cfloat
542
+ // cfloat @@@DEPRECATED_2.105@@@
543
+ deprecated class TypeInfo_q : TypeInfoGeneric! c_complex_float
456
544
{
545
+ override string toString () const pure nothrow @safe { return " cfloat" ; }
546
+
457
547
const : nothrow : pure : @trusted :
458
548
static if (__traits(hasMember, TypeInfo , " argTypes" ))
459
549
override int argTypes (out TypeInfo arg1, out TypeInfo arg2)
@@ -463,9 +553,11 @@ class TypeInfo_q : TypeInfoGeneric!cfloat
463
553
}
464
554
}
465
555
466
- // cdouble
467
- class TypeInfo_r : TypeInfoGeneric !cdouble
556
+ // cdouble @@@DEPRECATED_2.105@@@
557
+ deprecated class TypeInfo_r : TypeInfoGeneric! c_complex_double
468
558
{
559
+ override string toString () const pure nothrow @safe { return " cdouble" ; }
560
+
469
561
const : nothrow : pure : @trusted :
470
562
static if (__traits(hasMember, TypeInfo , " argTypes" ))
471
563
override int argTypes (out TypeInfo arg1, out TypeInfo arg2)
@@ -476,9 +568,11 @@ class TypeInfo_r : TypeInfoGeneric!cdouble
476
568
}
477
569
}
478
570
479
- // creal
480
- class TypeInfo_c : TypeInfoGeneric !creal
571
+ // creal @@@DEPRECATED_2.105@@@
572
+ deprecated class TypeInfo_c : TypeInfoGeneric! c_complex_real
481
573
{
574
+ override string toString () const pure nothrow @safe { return " creal" ; }
575
+
482
576
const : nothrow : pure : @trusted :
483
577
static if (__traits(hasMember, TypeInfo , " argTypes" ))
484
578
override int argTypes (out TypeInfo arg1, out TypeInfo arg2)
@@ -548,16 +642,50 @@ unittest
548
642
assert (! (a1 < b1 && b1 < a1)); // Original failing case
549
643
}
550
644
551
- // Arrays of all floating point types.
645
+ // Arrays of all simple floating- point types.
552
646
class TypeInfo_Af : TypeInfoArrayGeneric !float {}
553
- class TypeInfo_Ao : TypeInfoArrayGeneric !(ifloat, float) {}
554
647
class TypeInfo_Ad : TypeInfoArrayGeneric !double {}
555
- class TypeInfo_Ap : TypeInfoArrayGeneric !(idouble, double) {}
556
648
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
+ }
561
689
562
690
// void[] is a bit different, behaves like ubyte[] for comparison purposes.
563
691
class TypeInfo_Av : TypeInfo_Ah
0 commit comments