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

Commit f662007

Browse files
committed
Also reuse common implementation fragments for arrays
1 parent f14c296 commit f662007

File tree

1 file changed

+81
-74
lines changed

1 file changed

+81
-74
lines changed

src/rt/util/typeinfo.d

+81-74
Original file line numberDiff line numberDiff line change
@@ -267,21 +267,22 @@ unittest
267267
}();
268268
}
269269

270+
// Reduces to `T` if `cond` is `true` or `U` otherwise.
270271
private template Select(bool cond, T, U)
271272
{
272273
static if (cond) alias Select = T;
273274
else alias Select = U;
274275
}
275276

276-
/**
277+
/*
277278
TypeInfo 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
*/
286287
private class TypeInfoGeneric(T, Base = T) : Select!(is(T == Base), TypeInfo, TypeInfoGeneric!Base)
287288
if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
@@ -373,7 +374,7 @@ if (T.sizeof == Base.sizeof && T.alignof == Base.alignof)
373374
return RTInfo!T;
374375
}
375376

376-
static if (is(T == Base) && __traits(isFloating, T))
377+
static if (is(T == Base))
377378
static if (is(immutable T == immutable real) && T.mant_dig != 64) // exclude 80-bit X87
378379
// passed in SIMD register
379380
override @property uint flags() const { return 2; }
@@ -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 {}
524532
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) {}
527534
class TypeInfo_a : TypeInfoGeneric!(char, ubyte) {}
535+
class TypeInfo_t : TypeInfoGeneric!ushort {}
536+
class TypeInfo_s : TypeInfoGeneric!(short, ushort) {}
528537
class TypeInfo_u : TypeInfoGeneric!(wchar, ushort) {}
529538
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) {}
536543
static if (is(cent)) class TypeInfo_zi : TypeInfoGeneric!cent {}
537544
static 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 {}
602607
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) {}
604611
class TypeInfo_Axa : TypeInfoArrayGeneric!(const char) {}
605612
class 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 {}
611617
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) {}
614620
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) {}
617623
class TypeInfo_Am : TypeInfoArrayGeneric!ulong {}
624+
class TypeInfo_Al : TypeInfoArrayGeneric!(long, ulong) {}
618625

619626
private extern (C) void[] _adSort(void[] a, TypeInfo ti);
620627

@@ -656,11 +663,11 @@ unittest
656663

657664
// Arrays of all floating point types.
658665
class TypeInfo_Af : TypeInfoArrayGeneric!float {}
659-
class TypeInfo_Ao : TypeInfoArrayGeneric!ifloat {}
666+
class TypeInfo_Ao : TypeInfoArrayGeneric!(ifloat, float) {}
660667
class TypeInfo_Ad : TypeInfoArrayGeneric!double {}
661-
class TypeInfo_Ap : TypeInfoArrayGeneric!idouble {}
668+
class TypeInfo_Ap : TypeInfoArrayGeneric!(idouble, double) {}
662669
class TypeInfo_Ae : TypeInfoArrayGeneric!real {}
663-
class TypeInfo_Aj : TypeInfoArrayGeneric!ireal {}
670+
class TypeInfo_Aj : TypeInfoArrayGeneric!(ireal, real) {}
664671
class TypeInfo_Aq : TypeInfoArrayGeneric!cfloat {}
665672
class TypeInfo_Ar : TypeInfoArrayGeneric!cdouble {}
666673
class TypeInfo_Ac : TypeInfoArrayGeneric!creal {}

0 commit comments

Comments
 (0)