@@ -267,21 +267,24 @@ unittest
267267 }();
268268}
269269
270+ /*
271+ Reduces to `T` if `cond` is `true` or `U` otherwise.
272+ */
270273private template Select (bool cond, T, U)
271274{
272275 static if (cond) alias Select = T;
273276 else alias Select = U;
274277}
275278
276- /**
279+ /*
277280TypeInfo information for built-in types.
278281
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.
282+ A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
283+ equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example:
284+ `float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
285+ the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
286+ during compilation whether they have different signedness and override appropriately. For initializer, we
287+ detect if we need to override. The overriding initializer should be nonzero.
285288*/
286289private class TypeInfoGeneric (T, Base = T) : Select !(is(T == Base), TypeInfo, TypeInfoGeneric!Base)
287290if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
@@ -408,66 +411,72 @@ unittest
408411 }
409412}
410413
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- }
414+ /*
415+ TypeInfo information for arrays of built-in types.
420416
421- override bool opEquals (Object o) { return TypeInfo .opEquals (o); }
417+ A `Base` type may be specified, which must be a type with the same layout, alignment, hashing, and
418+ equality comparison as type `T`. This saves on code size because parts of `Base` will be reused. Example:
419+ `float` and `ifloat` or `char` and `ubyte`. The implementation assumes `Base` and `T` hash the same, swap
420+ the same, have the same ABI flags, and compare the same for equality. For ordering comparisons, we detect
421+ during compilation whether they have different signedness and override appropriately. For initializer, we
422+ detect if we need to override. The overriding initializer should be nonzero.
423+ */
424+ private class TypeInfoArrayGeneric (T, Base = T) : Select !(is(T == Base), TypeInfo_Array, TypeInfoArrayGeneric!Base)
425+ {
426+ static if (is (T == Base))
427+ override bool opEquals (Object o) { return TypeInfo .opEquals (o); }
422428
423429 override string toString () const { return (T[]).stringof; }
424430
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
431+ static if (is (T == Base))
432+ override size_t getHash (scope const void * p) @trusted const
440433 {
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 ;
434+ static if (__traits(isFloating, T))
435+ return Array! T.hashOf(* cast (T[]* )p);
436+ else
437+ return hashOf (* cast (const T[]* ) p);
446438 }
447- }
448439
449- override int compare (in void * p1, in void * p2) const
450- {
451- static if (__traits(isFloating, T))
440+ static if (is (T == Base))
441+ override bool equals (in void * p1, in void * p2) const
452442 {
453- return Array! Real.compare(* cast (Real[]* )p1, * cast (Real[]* )p2);
443+ static if (__traits(isFloating, T))
444+ {
445+ return Array! T.equals(* cast (T[]* )p1, * cast (T[]* )p2);
446+ }
447+ else
448+ {
449+ import core.stdc.string ;
450+ auto s1 = * cast (T[]* )p1;
451+ auto s2 = * cast (T[]* )p2;
452+ return s1.length == s2.length &&
453+ memcmp(s1.ptr, s2.ptr, s1.length) == 0 ;
454+ }
454455 }
455- else
456- {
457- auto s1 = * cast (T[]* )p1;
458- auto s2 = * cast (T[]* )p2;
459- auto len = s1.length;
460456
461- if (s2.length < len)
462- len = s2.length;
463- for (size_t u = 0 ; u < len; u++ )
457+ static if (is (T == Base) || (__traits(isIntegral, T) && T.max != Base.max))
458+ override int compare (in void * p1, in void * p2) const
459+ {
460+ static if (__traits(isFloating, T))
464461 {
465- if (int result = (s1[u] > s2[u]) - (s1[u] < s2[u]))
466- return result;
462+ return Array! T.compare(* cast (T[]* )p1, * cast (T[]* )p2);
463+ }
464+ else
465+ {
466+ auto s1 = * cast (T[]* )p1;
467+ auto s2 = * cast (T[]* )p2;
468+ auto len = s1.length;
469+
470+ if (s2.length < len)
471+ len = s2.length;
472+ for (size_t u = 0 ; u < len; u++ )
473+ {
474+ if (int result = (s1[u] > s2[u]) - (s1[u] < s2[u]))
475+ return result;
476+ }
477+ return (s1.length > s2.length) - (s1.length < s2.length);
467478 }
468- return (s1.length > s2.length) - (s1.length < s2.length);
469479 }
470- }
471480
472481 override @property inout (TypeInfo ) next() inout
473482 {
@@ -521,18 +530,18 @@ class TypeInfo_v : TypeInfoGeneric!ubyte
521530}
522531
523532// All integrals.
533+ class TypeInfo_h : TypeInfoGeneric !ubyte {}
524534class TypeInfo_b : TypeInfoGeneric !(bool, ubyte) {}
525- class TypeInfo_g : TypeInfoGeneric !byte {}
526- class TypeInfo_h : TypeInfoGeneric !(ubyte, byte) {}
535+ class TypeInfo_g : TypeInfoGeneric !(byte, ubyte) {}
527536class TypeInfo_a : TypeInfoGeneric !(char, ubyte) {}
537+ class TypeInfo_t : TypeInfoGeneric !ushort {}
538+ class TypeInfo_s : TypeInfoGeneric !(short, ushort) {}
528539class TypeInfo_u : TypeInfoGeneric !(wchar, ushort) {}
529540class 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) {}
541+ class TypeInfo_k : TypeInfoGeneric !uint {}
542+ class TypeInfo_i : TypeInfoGeneric !(int, uint) {}
543+ class TypeInfo_m : TypeInfoGeneric !ulong {}
544+ class TypeInfo_l : TypeInfoGeneric !(long, ulong) {}
536545static if (is (cent )) class TypeInfo_zi : TypeInfoGeneric! cent {}
537546static if (is (ucent )) class TypeInfo_zk : TypeInfoGeneric! ucent {}
538547
@@ -597,24 +606,24 @@ static if (__traits(hasMember, TypeInfo, "argTypes"))
597606 }
598607
599608// Arrays of all integrals.
600- class TypeInfo_Ab : TypeInfoArrayGeneric !bool {}
601- class TypeInfo_Ag : TypeInfoArrayGeneric !byte {}
602609class TypeInfo_Ah : TypeInfoArrayGeneric !ubyte {}
603- class TypeInfo_Aa : TypeInfoArrayGeneric !char {}
610+ class TypeInfo_Ab : TypeInfoArrayGeneric !(bool, ubyte) {}
611+ class TypeInfo_Ag : TypeInfoArrayGeneric !(byte, ubyte) {}
612+ class TypeInfo_Aa : TypeInfoArrayGeneric !(char, ubyte) {}
604613class TypeInfo_Axa : TypeInfoArrayGeneric !(const char) {}
605614class TypeInfo_Aya : TypeInfoArrayGeneric !(immutable char)
606615{
607616 // Must override this, otherwise "string" is returned.
608617 override string toString () const { return " immutable(char)[]" ; }
609618}
610- class TypeInfo_As : TypeInfoArrayGeneric !short {}
611619class TypeInfo_At : TypeInfoArrayGeneric !ushort {}
612- class TypeInfo_Au : TypeInfoArrayGeneric !wchar {}
613- class TypeInfo_Ai : TypeInfoArrayGeneric !int {}
620+ class TypeInfo_As : TypeInfoArrayGeneric !(short, ushort) {}
621+ class TypeInfo_Au : TypeInfoArrayGeneric !(wchar, ushort) {}
614622class TypeInfo_Ak : TypeInfoArrayGeneric !uint {}
615- class TypeInfo_Aw : TypeInfoArrayGeneric !dchar {}
616- class TypeInfo_Al : TypeInfoArrayGeneric !long {}
623+ class TypeInfo_Ai : TypeInfoArrayGeneric !(int, uint) {}
624+ class TypeInfo_Aw : TypeInfoArrayGeneric !(dchar, uint) {}
617625class TypeInfo_Am : TypeInfoArrayGeneric !ulong {}
626+ class TypeInfo_Al : TypeInfoArrayGeneric !(long, ulong) {}
618627
619628private extern (C) void [] _adSort(void [] a, TypeInfo ti);
620629
@@ -656,11 +665,11 @@ unittest
656665
657666// Arrays of all floating point types.
658667class TypeInfo_Af : TypeInfoArrayGeneric !float {}
659- class TypeInfo_Ao : TypeInfoArrayGeneric !ifloat {}
668+ class TypeInfo_Ao : TypeInfoArrayGeneric !( ifloat, float) {}
660669class TypeInfo_Ad : TypeInfoArrayGeneric !double {}
661- class TypeInfo_Ap : TypeInfoArrayGeneric !idouble {}
670+ class TypeInfo_Ap : TypeInfoArrayGeneric !( idouble, double) {}
662671class TypeInfo_Ae : TypeInfoArrayGeneric !real {}
663- class TypeInfo_Aj : TypeInfoArrayGeneric !ireal {}
672+ class TypeInfo_Aj : TypeInfoArrayGeneric !( ireal, real) {}
664673class TypeInfo_Aq : TypeInfoArrayGeneric !cfloat {}
665674class TypeInfo_Ar : TypeInfoArrayGeneric !cdouble {}
666675class TypeInfo_Ac : TypeInfoArrayGeneric !creal {}
0 commit comments