static bool usingCustomHash = false; struct S { enum baz = false; string bar(S* f) { return "ok"; } size_t toHash() const { debug usingCustomHash = true; return 42; } bool opEquals(ref const(S) rhs) const { return false; // <- always false } } // a HashablePointer!T mostly works like a T* would S x; HashablePointer!S ptr = &x; assert(ptr == &x); assert(ptr.baz == x.baz); assert(ptr.bar(ptr) == x.bar(&x)); // implicit conversion // equality checks may forward to the pointed-to element HashablePointer!S sameRef = ptr; assert(sameRef == ptr); assert(*sameRef != *ptr); // see S.opEquals, above // default raw pointer behaviour: bool[S*] withRaw; withRaw[&x] = true; debug assert(!usingCustomHash); // hashable pointer behaviour: bool[HashablePointer!S] withHashable; withHashable[ptr] = true; debug assert(usingCustomHash);
Generic pointer-like wrapper used to forward hash table operations to its pointed-to object.
This behaviour can be useful when one wishes to use references as hash table keys: whereas the default hash for pointers is solely based on the address it carries, using this wrapper as a key will call the pointed-to-type's custom hash and equality functions instead (if defined). Equality works similarly to object references: two wrappers always compare equal when their pointers are equal, and the object's opEquals only gets called when that's not the case.