@@ -424,6 +424,93 @@ class TypeInfo
424424 @property immutable (void )* rtInfo() nothrow pure const @safe @nogc { return rtinfoHasPointers; } // better safe than sorry
425425}
426426
427+ /*
428+ Run-time type information for scalar types (int for now).
429+ */
430+ template RTTypeid (T)
431+ if (is (T == int ))
432+ {
433+ class Impl : TypeInfo
434+ {
435+ const : nothrow : pure : @safe :
436+
437+ override bool opEquals (const Object rhs) @nogc
438+ {
439+ return this is rhs
440+ // Instance may be duplicated across DLLs, but has the same type.
441+ || cast (const Impl) rhs ! is null ;
442+ }
443+
444+ override int opCmp (const Object rhs)
445+ {
446+ if (this is rhs)
447+ return 0 ;
448+ if (auto ti = cast (const TypeInfo ) rhs)
449+ return __cmp (this .toString, ti.toString);
450+ return 1 ;
451+ }
452+
453+ override string toString () const pure nothrow @safe { return T.stringof; }
454+
455+ override size_t getHash (scope const void * p) @nogc @trusted
456+ {
457+ return * cast (const T * )p;
458+ }
459+
460+ override bool equals (in void * p1, in void * p2) @nogc @trusted
461+ {
462+ return * cast (const T * )p1 == * cast (const T * )p2;
463+ }
464+
465+ override int compare (in void * p1, in void * p2) @nogc @trusted
466+ {
467+ auto lhs = * cast (const T* ) p1, rhs = * cast (const T* ) p2;
468+ return int (lhs > rhs) - int (lhs < rhs);
469+ }
470+
471+ override @property size_t tsize() @nogc
472+ {
473+ return T.sizeof;
474+ }
475+
476+ override const (void )[] initializer () @trusted @nogc
477+ {
478+ static immutable T data;
479+ return (cast (const void * )&data)[0 .. T.sizeof];
480+ }
481+
482+ override void swap (void * p1, void * p2) @nogc @trusted
483+ {
484+ T t = * cast (T * )p1;
485+ * cast (T * )p1 = * cast (T * )p2;
486+ * cast (T * )p2 = t;
487+ }
488+
489+ override @property immutable (void )* rtInfo() { return rtinfoNoPointers; }
490+ }
491+
492+ // On-demand singleton object in static storage
493+ immutable RTTypeid = new Impl;
494+ }
495+
496+ unittest
497+ {
498+ alias id = RTTypeid! int ;
499+ static assert (id == id && id <= id && id >= id);
500+ static assert (id.toString == " int" );
501+ int a = 42 , b = 42 , c = 43 ;
502+ assert (id.getHash(&a) == 42 );
503+ assert (id.equals(&a, &b));
504+ assert (! id.equals(&a, &c));
505+ assert (id.compare(&a, &b) == 0 );
506+ assert (id.compare(&a, &c) == - 1 );
507+ assert (id.compare(&c, &a) == 1 );
508+ static assert (id.tsize == 4 );
509+ assert (cast (ubyte []) id.initializer() == [ 0 , 0 , 0 , 0 ]);
510+ id.swap(&a, &c);
511+ assert (a == 43 && c == 42 );
512+ }
513+
427514class TypeInfo_Enum : TypeInfo
428515{
429516 override string toString () const { return name; }
0 commit comments