10
10
module core.internal.hash ;
11
11
12
12
import core.internal.convert ;
13
- import core.internal.traits : allSatisfy;
13
+ import core.internal.traits : allSatisfy, Unconst ;
14
14
15
15
// If true ensure that positive zero and negative zero have the same hash.
16
16
// Historically typeid(float).getHash did this but hashOf(float) did not.
@@ -506,7 +506,7 @@ private enum _hashOfStruct =
506
506
q{
507
507
enum bool isChained = is (typeof (seed) : size_t );
508
508
static if (! isChained) enum size_t seed = 0 ;
509
- static if (hasCallableToHash! T ) // CTFE depends on toHash()
509
+ static if (hasCallableToHash! ( typeof (val)) ) // CTFE depends on toHash()
510
510
{
511
511
static if (isChained)
512
512
return hashOf (cast (size_t ) val.toHash(), seed);
517
517
{
518
518
static if (__traits(hasMember, T, " toHash" ) && is (typeof (T.toHash) == function ))
519
519
{
520
- pragma (msg, " Warning: struct " ~ __traits(identifier, T)~ " has method toHash, however it cannot be called with " ~ T.stringof~ " this." );
520
+ // TODO: in the future maybe this should be changed to a static
521
+ // assert(0), because if there's a `toHash` the programmer probably
522
+ // expected it to be called and a compilation failure here will
523
+ // expose a bug in his code.
524
+ // In the future we also might want to disallow non-const toHash
525
+ // altogether.
526
+ pragma (msg, " Warning: struct " ~ __traits(identifier, T)
527
+ ~ " has method toHash, however it cannot be called with "
528
+ ~ typeof (val).stringof~ " this." );
521
529
}
522
530
523
531
static if (T.tupleof.length == 0 )
553
561
// struct or union hash
554
562
size_t hashOf (T)(scope const auto ref T val, size_t seed = 0 )
555
563
if (! is (T == enum ) && (is (T == struct ) || is (T == union ))
564
+ && ! is (T == const ) && ! is (T == immutable )
556
565
&& canBitwiseHash! T)
557
566
{
558
567
mixin (_hashOfStruct);
@@ -574,6 +583,15 @@ if (!is(T == enum) && (is(T == struct) || is(T == union))
574
583
mixin (_hashOfStruct);
575
584
}
576
585
586
+ // struct or union hash - https://issues.dlang.org/show_bug.cgi?id=19332 (support might be removed in future)
587
+ size_t hashOf (T)(scope auto ref T val, size_t seed = 0 )
588
+ if (! is (T == enum ) && (is (T == struct ) || is (T == union ))
589
+ && (is (T == const ) || is (T == immutable ))
590
+ && canBitwiseHash! T && ! canBitwiseHash! (Unconst! T))
591
+ {
592
+ mixin (_hashOfStruct);
593
+ }
594
+
577
595
// delegate hash. CTFE unsupported
578
596
@trusted @nogc nothrow pure
579
597
size_t hashOf (T)(scope const T val, size_t seed = 0 ) if (! is (T == enum ) && is (T == delegate ))
0 commit comments