@@ -267,21 +267,22 @@ unittest
267
267
}();
268
268
}
269
269
270
+ // Reduces to `T` if `cond` is `true` or `U` otherwise.
270
271
private template Select (bool cond, T, U)
271
272
{
272
273
static if (cond) alias Select = T;
273
274
else alias Select = U;
274
275
}
275
276
276
- /**
277
+ /*
277
278
TypeInfo information for built-in types.
278
279
279
- Type `T` has the same layout and alignment as type `Base`, but slightly different behavior.
280
- Example: `float` and `ifloat` or `char` and `ubyte`.
281
- We assume the two types hash the same, swap the same, have the same ABI flags, and compare the same for
282
- equality. For ordering comparisons, we detect during compilation whether they have different min and max
283
- values (e.g. signed vs. unsigned) and override appropriately. For initializer, we detect if we need to
284
- override. The overriding initializer should be nonzero.
280
+ A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
281
+ equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example:
282
+ `float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
283
+ the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
284
+ during compilation whether they have different signedness and override appropriately. For initializer, we
285
+ detect if we need to override. The overriding initializer should be nonzero.
285
286
*/
286
287
private class TypeInfoGeneric (T, Base = T) : Select !(is(T == Base), TypeInfo, TypeInfoGeneric!Base)
287
288
if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
@@ -373,7 +374,7 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
373
374
return RTInfo ! T;
374
375
}
375
376
376
- static if (is (T == Base) && __traits(isFloating, T) )
377
+ static if (is (T == Base))
377
378
static if (is (immutable T == immutable real ) && T.mant_dig != 64 ) // exclude 80-bit X87
378
379
// passed in SIMD register
379
380
override @property uint flags() const { return 2 ; }
@@ -408,66 +409,72 @@ unittest
408
409
}
409
410
}
410
411
411
- private class TypeInfoArrayGeneric (T) : TypeInfo_Array
412
- {
413
- static if (__traits(isFloating, T))
414
- {
415
- static if (is (T == ifloat )) private alias Real = float ;
416
- else static if (is (T == idouble )) private alias Real = double ;
417
- else static if (is (T == ireal )) private alias Real = real ;
418
- else private alias Real = T;
419
- }
412
+ /* ¡
413
+ TypeInfo information for arrays of built-in types.
420
414
421
- override bool opEquals (Object o) { return TypeInfo .opEquals (o); }
415
+ A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
416
+ equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example:
417
+ `float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
418
+ the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
419
+ during compilation whether they have different signedness and override appropriately. For initializer, we
420
+ detect if we need to override. The overriding initializer should be nonzero.
421
+ */
422
+ private class TypeInfoArrayGeneric (T, Base = T) : Select !(is(T == Base), TypeInfo_Array, TypeInfoArrayGeneric!Base)
423
+ {
424
+ static if (is (T == Base))
425
+ override bool opEquals (Object o) { return TypeInfo .opEquals (o); }
422
426
423
427
override string toString () const { return (T[]).stringof; }
424
428
425
- override size_t getHash (scope const void * p) @trusted const
426
- {
427
- static if (__traits(isFloating, T))
428
- return Array! Real.hashOf(* cast (Real[]* )p);
429
- else
430
- return hashOf (* cast (const T[]* ) p);
431
- }
432
-
433
- override bool equals (in void * p1, in void * p2) const
434
- {
435
- static if (__traits(isFloating, T))
436
- {
437
- return Array! Real.equals(* cast (Real[]* )p1, * cast (Real[]* )p2);
438
- }
439
- else
429
+ static if (is (T == Base))
430
+ override size_t getHash (scope const void * p) @trusted const
440
431
{
441
- import core.stdc.string ;
442
- auto s1 = * cast (T[]* )p1;
443
- auto s2 = * cast (T[]* )p2;
444
- return s1.length == s2.length &&
445
- memcmp(s1.ptr, s2.ptr, s1.length) == 0 ;
432
+ static if (__traits(isFloating, T))
433
+ return Array! T.hashOf(* cast (T[]* )p);
434
+ else
435
+ return hashOf (* cast (const T[]* ) p);
446
436
}
447
- }
448
437
449
- override int compare (in void * p1, in void * p2) const
450
- {
451
- static if (__traits(isFloating, T))
438
+ static if (is (T == Base))
439
+ override bool equals (in void * p1, in void * p2) const
452
440
{
453
- return Array! Real.compare(* cast (Real[]* )p1, * cast (Real[]* )p2);
441
+ static if (__traits(isFloating, T))
442
+ {
443
+ return Array! T.equals(* cast (T[]* )p1, * cast (T[]* )p2);
444
+ }
445
+ else
446
+ {
447
+ import core.stdc.string ;
448
+ auto s1 = * cast (T[]* )p1;
449
+ auto s2 = * cast (T[]* )p2;
450
+ return s1.length == s2.length &&
451
+ memcmp(s1.ptr, s2.ptr, s1.length) == 0 ;
452
+ }
454
453
}
455
- else
456
- {
457
- auto s1 = * cast (T[]* )p1;
458
- auto s2 = * cast (T[]* )p2;
459
- auto len = s1.length;
460
454
461
- if (s2.length < len)
462
- len = s2.length;
463
- for (size_t u = 0 ; u < len; u++ )
455
+ static if (is (T == Base) || (__traits(isIntegral, T) && T.max != Base.max))
456
+ override int compare (in void * p1, in void * p2) const
457
+ {
458
+ static if (__traits(isFloating, T))
464
459
{
465
- if (int result = (s1[u] > s2[u]) - (s1[u] < s2[u]))
466
- return result;
460
+ return Array! T.compare(* cast (T[]* )p1, * cast (T[]* )p2);
461
+ }
462
+ else
463
+ {
464
+ auto s1 = * cast (T[]* )p1;
465
+ auto s2 = * cast (T[]* )p2;
466
+ auto len = s1.length;
467
+
468
+ if (s2.length < len)
469
+ len = s2.length;
470
+ for (size_t u = 0 ; u < len; u++ )
471
+ {
472
+ if (int result = (s1[u] > s2[u]) - (s1[u] < s2[u]))
473
+ return result;
474
+ }
475
+ return (s1.length > s2.length) - (s1.length < s2.length);
467
476
}
468
- return (s1.length > s2.length) - (s1.length < s2.length);
469
477
}
470
- }
471
478
472
479
override @property inout (TypeInfo ) next() inout
473
480
{
@@ -521,18 +528,18 @@ class TypeInfo_v : TypeInfoGeneric!ubyte
521
528
}
522
529
523
530
// All integrals.
531
+ class TypeInfo_h : TypeInfoGeneric !ubyte {}
524
532
class TypeInfo_b : TypeInfoGeneric !(bool, ubyte) {}
525
- class TypeInfo_g : TypeInfoGeneric !byte {}
526
- class TypeInfo_h : TypeInfoGeneric !(ubyte, byte) {}
533
+ class TypeInfo_g : TypeInfoGeneric !(byte, ubyte) {}
527
534
class TypeInfo_a : TypeInfoGeneric !(char, ubyte) {}
535
+ class TypeInfo_t : TypeInfoGeneric !ushort {}
536
+ class TypeInfo_s : TypeInfoGeneric !(short, ushort) {}
528
537
class TypeInfo_u : TypeInfoGeneric !(wchar, ushort) {}
529
538
class TypeInfo_w : TypeInfoGeneric !(dchar, uint) {}
530
- class TypeInfo_s : TypeInfoGeneric !short {}
531
- class TypeInfo_t : TypeInfoGeneric !(ushort, short) {}
532
- class TypeInfo_i : TypeInfoGeneric !int {}
533
- class TypeInfo_k : TypeInfoGeneric !(uint, int) {}
534
- class TypeInfo_l : TypeInfoGeneric !long {}
535
- class TypeInfo_m : TypeInfoGeneric !(ulong, long) {}
539
+ class TypeInfo_k : TypeInfoGeneric !uint {}
540
+ class TypeInfo_i : TypeInfoGeneric !(int, uint) {}
541
+ class TypeInfo_m : TypeInfoGeneric !ulong {}
542
+ class TypeInfo_l : TypeInfoGeneric !(long, ulong) {}
536
543
static if (is (cent )) class TypeInfo_zi : TypeInfoGeneric! cent {}
537
544
static if (is (ucent )) class TypeInfo_zk : TypeInfoGeneric! ucent {}
538
545
@@ -597,24 +604,24 @@ static if (__traits(hasMember, TypeInfo, "argTypes"))
597
604
}
598
605
599
606
// Arrays of all integrals.
600
- class TypeInfo_Ab : TypeInfoArrayGeneric !bool {}
601
- class TypeInfo_Ag : TypeInfoArrayGeneric !byte {}
602
607
class TypeInfo_Ah : TypeInfoArrayGeneric !ubyte {}
603
- class TypeInfo_Aa : TypeInfoArrayGeneric !char {}
608
+ class TypeInfo_Ab : TypeInfoArrayGeneric !(bool, ubyte) {}
609
+ class TypeInfo_Ag : TypeInfoArrayGeneric !(byte, ubyte) {}
610
+ class TypeInfo_Aa : TypeInfoArrayGeneric !(char, ubyte) {}
604
611
class TypeInfo_Axa : TypeInfoArrayGeneric !(const char) {}
605
612
class TypeInfo_Aya : TypeInfoArrayGeneric !(immutable char)
606
613
{
607
614
// Must override this, otherwise "string" is returned.
608
615
override string toString () const { return " immutable(char)[]" ; }
609
616
}
610
- class TypeInfo_As : TypeInfoArrayGeneric !short {}
611
617
class TypeInfo_At : TypeInfoArrayGeneric !ushort {}
612
- class TypeInfo_Au : TypeInfoArrayGeneric !wchar {}
613
- class TypeInfo_Ai : TypeInfoArrayGeneric !int {}
618
+ class TypeInfo_As : TypeInfoArrayGeneric !(short, ushort) {}
619
+ class TypeInfo_Au : TypeInfoArrayGeneric !(wchar, ushort) {}
614
620
class TypeInfo_Ak : TypeInfoArrayGeneric !uint {}
615
- class TypeInfo_Aw : TypeInfoArrayGeneric !dchar {}
616
- class TypeInfo_Al : TypeInfoArrayGeneric !long {}
621
+ class TypeInfo_Ai : TypeInfoArrayGeneric !(int, uint) {}
622
+ class TypeInfo_Aw : TypeInfoArrayGeneric !(dchar, uint) {}
617
623
class TypeInfo_Am : TypeInfoArrayGeneric !ulong {}
624
+ class TypeInfo_Al : TypeInfoArrayGeneric !(long, ulong) {}
618
625
619
626
private extern (C) void [] _adSort(void [] a, TypeInfo ti);
620
627
@@ -656,11 +663,11 @@ unittest
656
663
657
664
// Arrays of all floating point types.
658
665
class TypeInfo_Af : TypeInfoArrayGeneric !float {}
659
- class TypeInfo_Ao : TypeInfoArrayGeneric !ifloat {}
666
+ class TypeInfo_Ao : TypeInfoArrayGeneric !( ifloat, float) {}
660
667
class TypeInfo_Ad : TypeInfoArrayGeneric !double {}
661
- class TypeInfo_Ap : TypeInfoArrayGeneric !idouble {}
668
+ class TypeInfo_Ap : TypeInfoArrayGeneric !( idouble, double) {}
662
669
class TypeInfo_Ae : TypeInfoArrayGeneric !real {}
663
- class TypeInfo_Aj : TypeInfoArrayGeneric !ireal {}
670
+ class TypeInfo_Aj : TypeInfoArrayGeneric !( ireal, real) {}
664
671
class TypeInfo_Aq : TypeInfoArrayGeneric !cfloat {}
665
672
class TypeInfo_Ar : TypeInfoArrayGeneric !cdouble {}
666
673
class TypeInfo_Ac : TypeInfoArrayGeneric !creal {}
0 commit comments