@@ -424,6 +424,93 @@ class TypeInfo
424
424
@property immutable (void )* rtInfo() nothrow pure const @safe @nogc { return rtinfoHasPointers; } // better safe than sorry
425
425
}
426
426
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
+
427
514
class TypeInfo_Enum : TypeInfo
428
515
{
429
516
override string toString () const { return name; }
0 commit comments