@@ -267,21 +267,22 @@ unittest
267267 }();
268268}
269269
270+ // Reduces to `T` if `cond` is `true` or `U` otherwise.
270271private template Select (bool cond, T, U)
271272{
272273 static if (cond) alias Select = T;
273274 else alias Select = U;
274275}
275276
276- /**
277+ /*
277278TypeInfo information for built-in types.
278279
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.
285286*/
286287private class TypeInfoGeneric (T, Base = T) : Select !(is(T == Base), TypeInfo, TypeInfoGeneric!Base)
287288if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
@@ -408,66 +409,72 @@ unittest
408409 }
409410}
410411
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.
420414
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); }
422426
423427 override string toString () const { return (T[]).stringof; }
424428
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
440431 {
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);
446436 }
447- }
448437
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
452440 {
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+ }
454453 }
455- else
456- {
457- auto s1 = * cast (T[]* )p1;
458- auto s2 = * cast (T[]* )p2;
459- auto len = s1.length;
460454
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))
464459 {
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);
467476 }
468- return (s1.length > s2.length) - (s1.length < s2.length);
469477 }
470- }
471478
472479 override @property inout (TypeInfo ) next() inout
473480 {
@@ -521,18 +528,18 @@ class TypeInfo_v : TypeInfoGeneric!ubyte
521528}
522529
523530// All integrals.
531+ class TypeInfo_h : TypeInfoGeneric !ubyte {}
524532class 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) {}
527534class TypeInfo_a : TypeInfoGeneric !(char, ubyte) {}
535+ class TypeInfo_t : TypeInfoGeneric !ushort {}
536+ class TypeInfo_s : TypeInfoGeneric !(short, ushort) {}
528537class TypeInfo_u : TypeInfoGeneric !(wchar, ushort) {}
529538class 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) {}
536543static if (is (cent )) class TypeInfo_zi : TypeInfoGeneric! cent {}
537544static if (is (ucent )) class TypeInfo_zk : TypeInfoGeneric! ucent {}
538545
@@ -597,24 +604,24 @@ static if (__traits(hasMember, TypeInfo, "argTypes"))
597604 }
598605
599606// Arrays of all integrals.
600- class TypeInfo_Ab : TypeInfoArrayGeneric !bool {}
601- class TypeInfo_Ag : TypeInfoArrayGeneric !byte {}
602607class 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) {}
604611class TypeInfo_Axa : TypeInfoArrayGeneric !(const char) {}
605612class TypeInfo_Aya : TypeInfoArrayGeneric !(immutable char)
606613{
607614 // Must override this, otherwise "string" is returned.
608615 override string toString () const { return " immutable(char)[]" ; }
609616}
610- class TypeInfo_As : TypeInfoArrayGeneric !short {}
611617class 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) {}
614620class 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) {}
617623class TypeInfo_Am : TypeInfoArrayGeneric !ulong {}
624+ class TypeInfo_Al : TypeInfoArrayGeneric !(long, ulong) {}
618625
619626private extern (C) void [] _adSort(void [] a, TypeInfo ti);
620627
@@ -656,11 +663,11 @@ unittest
656663
657664// Arrays of all floating point types.
658665class TypeInfo_Af : TypeInfoArrayGeneric !float {}
659- class TypeInfo_Ao : TypeInfoArrayGeneric !ifloat {}
666+ class TypeInfo_Ao : TypeInfoArrayGeneric !( ifloat, float) {}
660667class TypeInfo_Ad : TypeInfoArrayGeneric !double {}
661- class TypeInfo_Ap : TypeInfoArrayGeneric !idouble {}
668+ class TypeInfo_Ap : TypeInfoArrayGeneric !( idouble, double) {}
662669class TypeInfo_Ae : TypeInfoArrayGeneric !real {}
663- class TypeInfo_Aj : TypeInfoArrayGeneric !ireal {}
670+ class TypeInfo_Aj : TypeInfoArrayGeneric !( ireal, real) {}
664671class TypeInfo_Aq : TypeInfoArrayGeneric !cfloat {}
665672class TypeInfo_Ar : TypeInfoArrayGeneric !cdouble {}
666673class TypeInfo_Ac : TypeInfoArrayGeneric !creal {}
0 commit comments