From 267fa2a06289c04200f720019050e7387f5e5a00 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Fri, 17 Jun 2016 01:03:20 -0700 Subject: [PATCH] use array interface to hashOf() --- src/object.d | 26 +++++++++++++++++--------- src/rt/typeinfo/ti_Ag.d | 4 ++-- src/rt/typeinfo/ti_Aint.d | 4 ++-- src/rt/typeinfo/ti_Along.d | 4 ++-- src/rt/typeinfo/ti_Ashort.d | 4 ++-- src/rt/typeinfo/ti_cent.d | 2 +- src/rt/typeinfo/ti_delegate.d | 2 +- src/rt/typeinfo/ti_long.d | 2 +- src/rt/typeinfo/ti_ucent.d | 2 +- src/rt/typeinfo/ti_ulong.d | 2 +- src/rt/util/container/hashtab.d | 6 +++--- src/rt/util/hash.d | 14 +++++++------- src/rt/util/typeinfo.d | 10 ++++++---- 13 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/object.d b/src/object.d index e48c0b3dff..8d8650e9d1 100644 --- a/src/object.d +++ b/src/object.d @@ -214,11 +214,11 @@ class TypeInfo { import core.internal.traits : externDFunc; alias hashOf = externDFunc!("rt.util.hash.hashOf", - size_t function(const(void)*, size_t, size_t) @trusted pure nothrow); + size_t function(const(void)[], size_t) @trusted pure nothrow @nogc); try { auto data = this.toString(); - return hashOf(data.ptr, data.length, 0); + return hashOf(data, 0); } catch (Throwable) { @@ -255,7 +255,15 @@ class TypeInfo return ti && this.toString() == ti.toString(); } - /// Returns a hash of the instance of a type. + /** + * Computes a hash of the instance of a type. + * Params: + * p = pointer to start of instance of the type + * Returns: + * the hash + * Bugs: + * fix https://issues.dlang.org/show_bug.cgi?id=12516 e.g. by changing this to a truly safe interface. + */ size_t getHash(in void* p) @trusted nothrow const { return cast(size_t)p; } /// Compares two instances for equality. @@ -1101,7 +1109,7 @@ class TypeInfo_Struct : TypeInfo this.initializer().length == s.initializer().length; } - override size_t getHash(in void* p) @safe pure nothrow const + override size_t getHash(in void* p) @trusted pure nothrow const { assert(p); if (xtoHash) @@ -1112,8 +1120,8 @@ class TypeInfo_Struct : TypeInfo { import core.internal.traits : externDFunc; alias hashOf = externDFunc!("rt.util.hash.hashOf", - size_t function(const(void)*, size_t, size_t) @trusted pure nothrow); - return hashOf(p, initializer().length, 0); + size_t function(const(void)[], size_t) @trusted pure nothrow @nogc); + return hashOf(p[0 .. initializer().length], 0); } } @@ -3167,7 +3175,7 @@ struct Test size_t hashOf(T)(auto ref T arg, size_t seed = 0) { import core.internal.hash; - return core.internal.hash.hashOf(arg, seed); + return core.internal.hash.hashOf((cast(void*)&arg)[0 .. T.sizeof], seed); } bool _xopEquals(in void*, in void*) @@ -3238,9 +3246,9 @@ private size_t getArrayHash(in TypeInfo element, in void* ptr, in size_t count) import core.internal.traits : externDFunc; alias hashOf = externDFunc!("rt.util.hash.hashOf", - size_t function(const(void)*, size_t, size_t) @trusted pure nothrow); + size_t function(const(void)[], size_t) @trusted pure nothrow @nogc); if(!hasCustomToHash(element)) - return hashOf(ptr, elementSize * count, 0); + return hashOf(ptr[0 .. elementSize * count], 0); size_t hash = 0; foreach(size_t i; 0 .. count) diff --git a/src/rt/typeinfo/ti_Ag.d b/src/rt/typeinfo/ti_Ag.d index 851c04356e..e9ededeb05 100644 --- a/src/rt/typeinfo/ti_Ag.d +++ b/src/rt/typeinfo/ti_Ag.d @@ -27,8 +27,8 @@ class TypeInfo_Ag : TypeInfo_Array override size_t getHash(in void* p) @trusted const { - byte[] s = *cast(byte[]*)p; - return rt.util.hash.hashOf(s.ptr, s.length * byte.sizeof); + const s = *cast(const void[]*)p; + return rt.util.hash.hashOf(s, 0); } override bool equals(in void* p1, in void* p2) const diff --git a/src/rt/typeinfo/ti_Aint.d b/src/rt/typeinfo/ti_Aint.d index 0bd0341b6e..52174e999f 100644 --- a/src/rt/typeinfo/ti_Aint.d +++ b/src/rt/typeinfo/ti_Aint.d @@ -28,8 +28,8 @@ class TypeInfo_Ai : TypeInfo_Array override size_t getHash(in void* p) @trusted const { - int[] s = *cast(int[]*)p; - return rt.util.hash.hashOf(s.ptr, s.length * int.sizeof); + const s = *cast(const int[]*)p; + return rt.util.hash.hashOf(s, 0); } override bool equals(in void* p1, in void* p2) const diff --git a/src/rt/typeinfo/ti_Along.d b/src/rt/typeinfo/ti_Along.d index 5439fee1af..ca0853a742 100644 --- a/src/rt/typeinfo/ti_Along.d +++ b/src/rt/typeinfo/ti_Along.d @@ -26,8 +26,8 @@ class TypeInfo_Al : TypeInfo_Array override size_t getHash(in void* p) @trusted const { - long[] s = *cast(long[]*)p; - return rt.util.hash.hashOf(s.ptr, s.length * long.sizeof); + const s = *cast(const long[]*)p; + return rt.util.hash.hashOf(s, 0); } override bool equals(in void* p1, in void* p2) const diff --git a/src/rt/typeinfo/ti_Ashort.d b/src/rt/typeinfo/ti_Ashort.d index d270abbffd..e5a2d4b8c0 100644 --- a/src/rt/typeinfo/ti_Ashort.d +++ b/src/rt/typeinfo/ti_Ashort.d @@ -26,8 +26,8 @@ class TypeInfo_As : TypeInfo_Array override size_t getHash(in void* p) @trusted const { - short[] s = *cast(short[]*)p; - return rt.util.hash.hashOf(s.ptr, s.length * short.sizeof); + const s = *cast(const short[]*)p; + return rt.util.hash.hashOf(s, 0); } override bool equals(in void* p1, in void* p2) const diff --git a/src/rt/typeinfo/ti_cent.d b/src/rt/typeinfo/ti_cent.d index d7e45da298..2898ab8e96 100644 --- a/src/rt/typeinfo/ti_cent.d +++ b/src/rt/typeinfo/ti_cent.d @@ -30,7 +30,7 @@ class TypeInfo_zi : TypeInfo override size_t getHash(in void* p) { - return rt.util.hash.hashOf(p, cent.sizeof); + return rt.util.hash.hashOf(p[0 .. cent.sizeof], 0); } override bool equals(in void* p1, in void* p2) diff --git a/src/rt/typeinfo/ti_delegate.d b/src/rt/typeinfo/ti_delegate.d index fa6b0a21e8..c5ed001e56 100644 --- a/src/rt/typeinfo/ti_delegate.d +++ b/src/rt/typeinfo/ti_delegate.d @@ -28,7 +28,7 @@ class TypeInfo_D : TypeInfo override size_t getHash(in void* p) { - return rt.util.hash.hashOf(p, dg.sizeof); + return rt.util.hash.hashOf(p[0 .. dg.sizeof], 0); } override bool equals(in void* p1, in void* p2) diff --git a/src/rt/typeinfo/ti_long.d b/src/rt/typeinfo/ti_long.d index d054022b26..4328a23a9c 100644 --- a/src/rt/typeinfo/ti_long.d +++ b/src/rt/typeinfo/ti_long.d @@ -28,7 +28,7 @@ class TypeInfo_l : TypeInfo override size_t getHash(in void* p) { - return rt.util.hash.hashOf(p, long.sizeof); + return rt.util.hash.hashOf(p[0 .. long.sizeof], 0); } override bool equals(in void* p1, in void* p2) diff --git a/src/rt/typeinfo/ti_ucent.d b/src/rt/typeinfo/ti_ucent.d index 0f04253aaf..e5f95cf963 100644 --- a/src/rt/typeinfo/ti_ucent.d +++ b/src/rt/typeinfo/ti_ucent.d @@ -30,7 +30,7 @@ class TypeInfo_zk : TypeInfo override size_t getHash(in void* p) { - return rt.util.hash.hashOf(p, ucent.sizeof); + return rt.util.hash.hashOf(p[0 .. ucent.sizeof], 0); } override bool equals(in void* p1, in void* p2) diff --git a/src/rt/typeinfo/ti_ulong.d b/src/rt/typeinfo/ti_ulong.d index af645a1a42..9e949c44ac 100644 --- a/src/rt/typeinfo/ti_ulong.d +++ b/src/rt/typeinfo/ti_ulong.d @@ -28,7 +28,7 @@ class TypeInfo_m : TypeInfo override size_t getHash(in void* p) { - return rt.util.hash.hashOf(p, ulong.sizeof); + return rt.util.hash.hashOf(p[0 .. ulong.sizeof]); } override bool equals(in void* p1, in void* p2) diff --git a/src/rt/util/container/hashtab.d b/src/rt/util/container/hashtab.d index ef41b75811..2b4ab5d609 100644 --- a/src/rt/util/container/hashtab.d +++ b/src/rt/util/container/hashtab.d @@ -144,13 +144,13 @@ private: return &p._value; } - static hash_t hashOf(in ref Key key) + static hash_t hashOf(in ref Key key) @trusted { import rt.util.hash : hashOf; static if (is(Key U : U[])) - return hashOf(cast(const ubyte*)key.ptr, key.length * key[0].sizeof); + return hashOf(key, 0); else - return hashOf(cast(const ubyte*)&key, Key.sizeof); + return hashOf((&key)[0 .. 1], 0); } @property hash_t mask() const diff --git a/src/rt/util/hash.d b/src/rt/util/hash.d index 32198605aa..eb94cc0b04 100644 --- a/src/rt/util/hash.d +++ b/src/rt/util/hash.d @@ -17,14 +17,14 @@ version( AnyX86 ) version = HasUnalignedOps; -@trusted pure nothrow +@trusted pure nothrow @nogc size_t hashOf( const(void)[] buf, size_t seed = 0 ) { return hashOf(buf.ptr, buf.length, seed); } -@trusted pure nothrow -size_t hashOf( const(void)* buf, size_t len, size_t seed = 0 ) +@system pure nothrow @nogc +size_t hashOf( const(void)* buf, size_t len, size_t seed ) { /* * This is Paul Hsieh's SuperFastHash algorithm, described here: @@ -32,7 +32,7 @@ size_t hashOf( const(void)* buf, size_t len, size_t seed = 0 ) * It is protected by the following open source license: * http://www.azillionmonkeys.com/qed/weblicense.html */ - static uint get16bits( const (ubyte)* x ) pure nothrow + static uint get16bits( const (ubyte)* x ) pure nothrow @nogc { // CTFE doesn't support casting ubyte* -> ushort*, so revert to // per-byte access when in CTFE. @@ -96,14 +96,14 @@ size_t hashOf( const(void)* buf, size_t len, size_t seed = 0 ) } // Check that hashOf works with CTFE -unittest +@nogc nothrow pure unittest { size_t ctfeHash(string x) { - return hashOf(x.ptr, x.length); + return hashOf(x.ptr, x.length, 0); } enum test_str = "Sample string"; enum size_t hashVal = ctfeHash(test_str); - assert(hashVal == hashOf(test_str.ptr, test_str.length)); + assert(hashVal == hashOf(test_str.ptr, test_str.length, 0)); } diff --git a/src/rt/util/typeinfo.d b/src/rt/util/typeinfo.d index 8c41e0a13b..6cb26043f3 100644 --- a/src/rt/util/typeinfo.d +++ b/src/rt/util/typeinfo.d @@ -7,8 +7,6 @@ */ module rt.util.typeinfo; -public import rt.util.hash; - template Floating(T) if (is(T == float) || is(T == double) || is(T == real)) { @@ -42,7 +40,10 @@ if (is(T == float) || is(T == double) || is(T == real)) static if (is(T == float)) // special case? return *cast(uint*)&value; else - return rt.util.hash.hashOf(&value, T.sizeof); + { + import rt.util.hash; + return rt.util.hash.hashOf((&value)[0 .. 1], 0); + } } } template Floating(T) @@ -76,7 +77,8 @@ if (is(T == cfloat) || is(T == cdouble) || is(T == creal)) { if (value == 0 + 0i) value = 0 + 0i; - return rt.util.hash.hashOf(&value, T.sizeof); + import rt.util.hash; + return rt.util.hash.hashOf((&value)[0 .. 1], 0); } }