Commit e613d992 by Iain Buclaw Committed by Iain Buclaw

libphobos: Apply core.internal.hash updates from druntime

Backported from upstream druntime 2.084

Reviewed-on: https://github.com/dlang/druntime/pull/2469

libphobos/ChangeLog:

	* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Remove rt/util/hash.d
	* libdruntime/Makefile.in: Rebuild.
	* testsuite/libphobos.aa/aa.exp: New file.
	* testsuite/libphobos.aa/test_aa.d: New test.
	* testsuite/libphobos.hash/hash.exp: New file.
	* testsuite/libphobos.hash/test_hash.d: New test.

From-SVN: r268754
parent f1b7b50a
2019-02-10 Iain Buclaw <ibuclaw@gdcproject.org>
* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Remove rt/util/hash.d
* libdruntime/Makefile.in: Rebuild.
* testsuite/libphobos.aa/aa.exp: New file.
* testsuite/libphobos.aa/test_aa.d: New test.
* testsuite/libphobos.hash/hash.exp: New file.
* testsuite/libphobos.hash/test_hash.d: New test.
2019-01-12 Iain Buclaw <ibuclaw@gdcproject.org> 2019-01-12 Iain Buclaw <ibuclaw@gdcproject.org>
* README.gcc: New file. * README.gcc: New file.
......
f2db21937e650553066c30f1a9d5a7d08a1b3573 cc215408bbdbc3324a95080aeef31287f663e57c
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository. merge done from the dlang/druntime repository.
...@@ -197,8 +197,8 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ ...@@ -197,8 +197,8 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
rt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \ rt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \
rt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \ rt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \
rt/util/array.d rt/util/container/array.d rt/util/container/common.d \ rt/util/array.d rt/util/container/array.d rt/util/container/common.d \
rt/util/container/hashtab.d rt/util/container/treap.d rt/util/hash.d \ rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \
rt/util/random.d rt/util/typeinfo.d rt/util/utf.d rt/util/typeinfo.d rt/util/utf.d
DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
core/stdcpp/typeinfo.d core/stdcpp/typeinfo.d
......
...@@ -229,8 +229,7 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \ ...@@ -229,8 +229,7 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
rt/typeinfo/ti_wchar.lo rt/util/array.lo \ rt/typeinfo/ti_wchar.lo rt/util/array.lo \
rt/util/container/array.lo rt/util/container/common.lo \ rt/util/container/array.lo rt/util/container/common.lo \
rt/util/container/hashtab.lo rt/util/container/treap.lo \ rt/util/container/hashtab.lo rt/util/container/treap.lo \
rt/util/hash.lo rt/util/random.lo rt/util/typeinfo.lo \ rt/util/random.lo rt/util/typeinfo.lo rt/util/utf.lo
rt/util/utf.lo
am__objects_2 = gc/bits.lo gc/config.lo gc/gcinterface.lo \ am__objects_2 = gc/bits.lo gc/config.lo gc/gcinterface.lo \
gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \ gc/impl/conservative/gc.lo gc/impl/manual/gc.lo gc/os.lo \
gc/pooltable.lo gc/proxy.lo gc/pooltable.lo gc/proxy.lo
...@@ -831,8 +830,8 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ ...@@ -831,8 +830,8 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
rt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \ rt/typeinfo/ti_ucent.d rt/typeinfo/ti_uint.d rt/typeinfo/ti_ulong.d \
rt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \ rt/typeinfo/ti_ushort.d rt/typeinfo/ti_void.d rt/typeinfo/ti_wchar.d \
rt/util/array.d rt/util/container/array.d rt/util/container/common.d \ rt/util/array.d rt/util/container/array.d rt/util/container/common.d \
rt/util/container/hashtab.d rt/util/container/treap.d rt/util/hash.d \ rt/util/container/hashtab.d rt/util/container/treap.d rt/util/random.d \
rt/util/random.d rt/util/typeinfo.d rt/util/utf.d rt/util/typeinfo.d rt/util/utf.d
DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \ DRUNTIME_DSOURCES_STDCXX = core/stdcpp/exception.d \
core/stdcpp/typeinfo.d core/stdcpp/typeinfo.d
...@@ -1256,7 +1255,6 @@ rt/util/container/array.lo: rt/util/container/$(am__dirstamp) ...@@ -1256,7 +1255,6 @@ rt/util/container/array.lo: rt/util/container/$(am__dirstamp)
rt/util/container/common.lo: rt/util/container/$(am__dirstamp) rt/util/container/common.lo: rt/util/container/$(am__dirstamp)
rt/util/container/hashtab.lo: rt/util/container/$(am__dirstamp) rt/util/container/hashtab.lo: rt/util/container/$(am__dirstamp)
rt/util/container/treap.lo: rt/util/container/$(am__dirstamp) rt/util/container/treap.lo: rt/util/container/$(am__dirstamp)
rt/util/hash.lo: rt/util/$(am__dirstamp)
rt/util/random.lo: rt/util/$(am__dirstamp) rt/util/random.lo: rt/util/$(am__dirstamp)
rt/util/typeinfo.lo: rt/util/$(am__dirstamp) rt/util/typeinfo.lo: rt/util/$(am__dirstamp)
rt/util/utf.lo: rt/util/$(am__dirstamp) rt/util/utf.lo: rt/util/$(am__dirstamp)
......
...@@ -128,6 +128,30 @@ template dtorIsNothrow(T) ...@@ -128,6 +128,30 @@ template dtorIsNothrow(T)
enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow); enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow);
} }
/*
Tests whether all given items satisfy a template predicate, i.e. evaluates to
$(D F!(T[0]) && F!(T[1]) && ... && F!(T[$ - 1])).
*/
package(core.internal)
template allSatisfy(alias F, T...)
{
static if (T.length == 0)
{
enum allSatisfy = true;
}
else static if (T.length == 1)
{
enum allSatisfy = F!(T[0]);
}
else
{
static if (allSatisfy!(F, T[0 .. $/2]))
enum allSatisfy = allSatisfy!(F, T[$/2 .. $]);
else
enum allSatisfy = false;
}
}
template anySatisfy(alias F, T...) template anySatisfy(alias F, T...)
{ {
static if (T.length == 0) static if (T.length == 0)
......
...@@ -25,7 +25,7 @@ class TypeInfo_Ar : TypeInfo_Array ...@@ -25,7 +25,7 @@ class TypeInfo_Ar : TypeInfo_Array
override string toString() const { return (F[]).stringof; } override string toString() const { return (F[]).stringof; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
return Array!F.hashOf(*cast(F[]*)p); return Array!F.hashOf(*cast(F[]*)p);
} }
......
...@@ -25,7 +25,7 @@ class TypeInfo_Aq : TypeInfo_Array ...@@ -25,7 +25,7 @@ class TypeInfo_Aq : TypeInfo_Array
override string toString() const { return (F[]).stringof; } override string toString() const { return (F[]).stringof; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
return Array!F.hashOf(*cast(F[]*)p); return Array!F.hashOf(*cast(F[]*)p);
} }
......
...@@ -25,7 +25,7 @@ class TypeInfo_Ac : TypeInfo_Array ...@@ -25,7 +25,7 @@ class TypeInfo_Ac : TypeInfo_Array
override string toString() const { return (F[]).stringof; } override string toString() const { return (F[]).stringof; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
return Array!F.hashOf(*cast(F[]*)p); return Array!F.hashOf(*cast(F[]*)p);
} }
......
...@@ -25,7 +25,7 @@ class TypeInfo_Ad : TypeInfo_Array ...@@ -25,7 +25,7 @@ class TypeInfo_Ad : TypeInfo_Array
override string toString() const { return (F[]).stringof; } override string toString() const { return (F[]).stringof; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
return Array!F.hashOf(*cast(F[]*)p); return Array!F.hashOf(*cast(F[]*)p);
} }
......
...@@ -25,7 +25,7 @@ class TypeInfo_Af : TypeInfo_Array ...@@ -25,7 +25,7 @@ class TypeInfo_Af : TypeInfo_Array
override string toString() const { return (F[]).stringof; } override string toString() const { return (F[]).stringof; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
return Array!F.hashOf(*cast(F[]*)p); return Array!F.hashOf(*cast(F[]*)p);
} }
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
module rt.typeinfo.ti_Ag; module rt.typeinfo.ti_Ag;
private import core.stdc.string; private import core.stdc.string;
private import rt.util.hash;
private import core.internal.string; private import core.internal.string;
// byte[] // byte[]
...@@ -25,10 +24,10 @@ class TypeInfo_Ag : TypeInfo_Array ...@@ -25,10 +24,10 @@ class TypeInfo_Ag : TypeInfo_Array
override string toString() const { return "byte[]"; } override string toString() const { return "byte[]"; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
const s = *cast(const void[]*)p; const s = *cast(const void[]*)p;
return rt.util.hash.hashOf(s, 0); return hashOf(s);
} }
override bool equals(in void* p1, in void* p2) const override bool equals(in void* p1, in void* p2) const
...@@ -118,54 +117,10 @@ class TypeInfo_Aa : TypeInfo_Ah ...@@ -118,54 +117,10 @@ class TypeInfo_Aa : TypeInfo_Ah
{ {
override string toString() const { return "char[]"; } override string toString() const { return "char[]"; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
char[] s = *cast(char[]*)p; char[] s = *cast(char[]*)p;
size_t hash = 0; return hashOf(s);
version (all)
{
foreach (char c; s)
hash = hash * 11 + c;
}
else
{
size_t len = s.length;
char *str = s;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 9;
hash += *cast(ubyte *)str;
return hash;
case 2:
hash *= 9;
hash += *cast(ushort *)str;
return hash;
case 3:
hash *= 9;
hash += (*cast(ushort *)str << 8) +
(cast(ubyte *)str)[2];
return hash;
default:
hash *= 9;
hash += *cast(uint *)str;
str += 4;
len -= 4;
break;
}
}
}
return hash;
} }
override @property inout(TypeInfo) next() inout override @property inout(TypeInfo) next() inout
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
module rt.typeinfo.ti_Aint; module rt.typeinfo.ti_Aint;
private import core.stdc.string; private import core.stdc.string;
private import rt.util.hash;
extern (C) void[] _adSort(void[] a, TypeInfo ti); extern (C) void[] _adSort(void[] a, TypeInfo ti);
...@@ -26,10 +25,11 @@ class TypeInfo_Ai : TypeInfo_Array ...@@ -26,10 +25,11 @@ class TypeInfo_Ai : TypeInfo_Array
override string toString() const { return "int[]"; } override string toString() const { return "int[]"; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
const s = *cast(const int[]*)p; // Hash as if unsigned.
return rt.util.hash.hashOf(s, 0); const s = *cast(const uint[]*)p;
return hashOf(s);
} }
override bool equals(in void* p1, in void* p2) const override bool equals(in void* p1, in void* p2) const
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
module rt.typeinfo.ti_Along; module rt.typeinfo.ti_Along;
private import core.stdc.string; private import core.stdc.string;
private import rt.util.hash;
// long[] // long[]
...@@ -24,10 +23,11 @@ class TypeInfo_Al : TypeInfo_Array ...@@ -24,10 +23,11 @@ class TypeInfo_Al : TypeInfo_Array
override string toString() const { return "long[]"; } override string toString() const { return "long[]"; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
const s = *cast(const long[]*)p; // Hash as if unsigned.
return rt.util.hash.hashOf(s, 0); const s = *cast(const ulong[]*)p;
return hashOf(s);
} }
override bool equals(in void* p1, in void* p2) const override bool equals(in void* p1, in void* p2) const
......
...@@ -25,7 +25,7 @@ class TypeInfo_Ae : TypeInfo_Array ...@@ -25,7 +25,7 @@ class TypeInfo_Ae : TypeInfo_Array
override string toString() const { return (F[]).stringof; } override string toString() const { return (F[]).stringof; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
return Array!F.hashOf(*cast(F[]*)p); return Array!F.hashOf(*cast(F[]*)p);
} }
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
module rt.typeinfo.ti_Ashort; module rt.typeinfo.ti_Ashort;
private import core.stdc.string; private import core.stdc.string;
private import rt.util.hash;
// short[] // short[]
...@@ -24,10 +23,11 @@ class TypeInfo_As : TypeInfo_Array ...@@ -24,10 +23,11 @@ class TypeInfo_As : TypeInfo_Array
override string toString() const { return "short[]"; } override string toString() const { return "short[]"; }
override size_t getHash(in void* p) @trusted const override size_t getHash(scope const void* p) @trusted const
{ {
const s = *cast(const short[]*)p; // Hash as if unsigned.
return rt.util.hash.hashOf(s, 0); const s = *cast(const ushort[]*)p;
return hashOf(s);
} }
override bool equals(in void* p1, in void* p2) const override bool equals(in void* p1, in void* p2) const
......
...@@ -22,7 +22,7 @@ class TypeInfo_C : TypeInfo ...@@ -22,7 +22,7 @@ class TypeInfo_C : TypeInfo
//pure: //pure:
//nothrow: //nothrow:
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
Object o = *cast(Object*)p; Object o = *cast(Object*)p;
return o ? o.toHash() : 0; return o ? o.toHash() : 0;
......
...@@ -24,9 +24,9 @@ class TypeInfo_g : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_g : TypeInfo
override string toString() const pure nothrow @safe { return "byte"; } override string toString() const pure nothrow @safe { return "byte"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(byte *)p; return *cast(const byte *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -27,7 +27,7 @@ class TypeInfo_r : TypeInfo ...@@ -27,7 +27,7 @@ class TypeInfo_r : TypeInfo
override string toString() const { return F.stringof; } override string toString() const { return F.stringof; }
override size_t getHash(in void* p) const @trusted override size_t getHash(scope const void* p) const @trusted
{ {
return Floating!F.hashOf(*cast(F*)p); return Floating!F.hashOf(*cast(F*)p);
} }
......
...@@ -13,8 +13,6 @@ ...@@ -13,8 +13,6 @@
*/ */
module rt.typeinfo.ti_cent; module rt.typeinfo.ti_cent;
private import rt.util.hash;
static if (is(cent)): static if (is(cent)):
// cent // cent
...@@ -28,9 +26,10 @@ class TypeInfo_zi : TypeInfo ...@@ -28,9 +26,10 @@ class TypeInfo_zi : TypeInfo
override string toString() const pure nothrow @safe { return "cent"; } override string toString() const pure nothrow @safe { return "cent"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return rt.util.hash.hashOf(p[0 .. cent.sizeof], 0); // cent & ucent hash the same if ucent.sizeof >= size_t.sizeof.
return hashOf(*cast(const ucent*) p);
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -27,7 +27,7 @@ class TypeInfo_q : TypeInfo ...@@ -27,7 +27,7 @@ class TypeInfo_q : TypeInfo
override string toString() const { return F.stringof; } override string toString() const { return F.stringof; }
override size_t getHash(in void* p) const @trusted override size_t getHash(scope const void* p) const @trusted
{ {
return Floating!F.hashOf(*cast(F*)p); return Floating!F.hashOf(*cast(F*)p);
} }
......
...@@ -24,9 +24,9 @@ class TypeInfo_a : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_a : TypeInfo
override string toString() const pure nothrow @safe { return "char"; } override string toString() const pure nothrow @safe { return "char"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(char *)p; return *cast(const char *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -27,7 +27,7 @@ class TypeInfo_c : TypeInfo ...@@ -27,7 +27,7 @@ class TypeInfo_c : TypeInfo
override string toString() const { return F.stringof; } override string toString() const { return F.stringof; }
override size_t getHash(in void* p) const @trusted override size_t getHash(scope const void* p) const @trusted
{ {
return Floating!F.hashOf(*cast(F*)p); return Floating!F.hashOf(*cast(F*)p);
} }
......
...@@ -24,9 +24,9 @@ class TypeInfo_w : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_w : TypeInfo
override string toString() const pure nothrow @safe { return "dchar"; } override string toString() const pure nothrow @safe { return "dchar"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(dchar *)p; return *cast(const dchar *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
*/ */
module rt.typeinfo.ti_delegate; module rt.typeinfo.ti_delegate;
private import rt.util.hash;
// delegate // delegate
...@@ -26,9 +25,9 @@ class TypeInfo_D : TypeInfo ...@@ -26,9 +25,9 @@ class TypeInfo_D : TypeInfo
pure: pure:
nothrow: nothrow:
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return rt.util.hash.hashOf(p[0 .. dg.sizeof], 0); return hashOf(*cast(dg*)p);
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -27,7 +27,7 @@ class TypeInfo_d : TypeInfo ...@@ -27,7 +27,7 @@ class TypeInfo_d : TypeInfo
override string toString() const { return F.stringof; } override string toString() const { return F.stringof; }
override size_t getHash(in void* p) const @trusted override size_t getHash(scope const void* p) const @trusted
{ {
return Floating!F.hashOf(*cast(F*)p); return Floating!F.hashOf(*cast(F*)p);
} }
......
...@@ -27,7 +27,7 @@ class TypeInfo_f : TypeInfo ...@@ -27,7 +27,7 @@ class TypeInfo_f : TypeInfo
override string toString() const { return F.stringof; } override string toString() const { return F.stringof; }
override size_t getHash(in void* p) const @trusted override size_t getHash(scope const void* p) const @trusted
{ {
return Floating!F.hashOf(*cast(F*)p); return Floating!F.hashOf(*cast(F*)p);
} }
......
...@@ -24,9 +24,9 @@ class TypeInfo_i : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_i : TypeInfo
override string toString() const pure nothrow @safe { return "int"; } override string toString() const pure nothrow @safe { return "int"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(uint *)p; return *cast(const int *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -13,8 +13,6 @@ ...@@ -13,8 +13,6 @@
*/ */
module rt.typeinfo.ti_long; module rt.typeinfo.ti_long;
private import rt.util.hash;
// long // long
class TypeInfo_l : TypeInfo class TypeInfo_l : TypeInfo
...@@ -26,9 +24,13 @@ class TypeInfo_l : TypeInfo ...@@ -26,9 +24,13 @@ class TypeInfo_l : TypeInfo
override string toString() const pure nothrow @safe { return "long"; } override string toString() const pure nothrow @safe { return "long"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return rt.util.hash.hashOf(p[0 .. long.sizeof], 0); static if (ulong.sizeof <= size_t.sizeof)
return *cast(const long*)p;
else
// long & ulong hash the same if ulong.sizeof > size_t.sizeof.
return hashOf(*cast(const ulong*)p);
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -19,7 +19,7 @@ class TypeInfo_n : TypeInfo ...@@ -19,7 +19,7 @@ class TypeInfo_n : TypeInfo
{ {
override string toString() const @safe { return "typeof(null)"; } override string toString() const @safe { return "typeof(null)"; }
override size_t getHash(in void* p) const override size_t getHash(scope const void* p) const
{ {
return 0; return 0;
} }
......
...@@ -23,9 +23,10 @@ class TypeInfo_P : TypeInfo ...@@ -23,9 +23,10 @@ class TypeInfo_P : TypeInfo
pure: pure:
nothrow: nothrow:
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return cast(size_t)*cast(void**)p; size_t addr = cast(size_t) *cast(const void**)p;
return addr ^ (addr >> 4);
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -27,7 +27,7 @@ class TypeInfo_e : TypeInfo ...@@ -27,7 +27,7 @@ class TypeInfo_e : TypeInfo
override string toString() const { return F.stringof; } override string toString() const { return F.stringof; }
override size_t getHash(in void* p) const @trusted override size_t getHash(scope const void* p) const @trusted
{ {
return Floating!F.hashOf(*cast(F*)p); return Floating!F.hashOf(*cast(F*)p);
} }
......
...@@ -24,9 +24,9 @@ class TypeInfo_s : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_s : TypeInfo
override string toString() const pure nothrow @safe { return "short"; } override string toString() const pure nothrow @safe { return "short"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(short *)p; return *cast(const short *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -24,9 +24,9 @@ class TypeInfo_h : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_h : TypeInfo
override string toString() const pure nothrow @safe { return "ubyte"; } override string toString() const pure nothrow @safe { return "ubyte"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(ubyte *)p; return *cast(const ubyte *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -13,8 +13,6 @@ ...@@ -13,8 +13,6 @@
*/ */
module rt.typeinfo.ti_ucent; module rt.typeinfo.ti_ucent;
private import rt.util.hash;
static if (is(ucent)): static if (is(ucent)):
// ucent // ucent
...@@ -28,9 +26,9 @@ class TypeInfo_zk : TypeInfo ...@@ -28,9 +26,9 @@ class TypeInfo_zk : TypeInfo
override string toString() const pure nothrow @safe { return "ucent"; } override string toString() const pure nothrow @safe { return "ucent"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return rt.util.hash.hashOf(p[0 .. ucent.sizeof], 0); return hashOf(*cast(const ucent*) p);
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -24,9 +24,9 @@ class TypeInfo_k : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_k : TypeInfo
override string toString() const pure nothrow @safe { return "uint"; } override string toString() const pure nothrow @safe { return "uint"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(uint *)p; return *cast(const uint *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
*/ */
module rt.typeinfo.ti_ulong; module rt.typeinfo.ti_ulong;
private import rt.util.hash;
// ulong // ulong
...@@ -26,9 +25,12 @@ class TypeInfo_m : TypeInfo ...@@ -26,9 +25,12 @@ class TypeInfo_m : TypeInfo
override string toString() const pure nothrow @safe { return "ulong"; } override string toString() const pure nothrow @safe { return "ulong"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return rt.util.hash.hashOf(p[0 .. ulong.sizeof], 0); static if (ulong.sizeof <= size_t.sizeof)
return *cast(const ulong*)p;
else
return hashOf(*cast(const ulong*)p);
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -24,9 +24,9 @@ class TypeInfo_t : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_t : TypeInfo
override string toString() const pure nothrow @safe { return "ushort"; } override string toString() const pure nothrow @safe { return "ushort"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(ushort *)p; return *cast(const ushort *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -24,7 +24,7 @@ class TypeInfo_v : TypeInfo ...@@ -24,7 +24,7 @@ class TypeInfo_v : TypeInfo
override string toString() const pure nothrow @safe { return "void"; } override string toString() const pure nothrow @safe { return "void"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
assert(0); assert(0);
} }
......
...@@ -24,9 +24,9 @@ class TypeInfo_u : TypeInfo ...@@ -24,9 +24,9 @@ class TypeInfo_u : TypeInfo
override string toString() { return "wchar"; } override string toString() { return "wchar"; }
override size_t getHash(in void* p) override size_t getHash(scope const void* p)
{ {
return *cast(wchar *)p; return *cast(const wchar *)p;
} }
override bool equals(in void* p1, in void* p2) override bool equals(in void* p1, in void* p2)
......
...@@ -146,11 +146,10 @@ private: ...@@ -146,11 +146,10 @@ private:
static hash_t hashOf(in ref Key key) @trusted static hash_t hashOf(in ref Key key) @trusted
{ {
import rt.util.hash : hashOf;
static if (is(Key U : U[])) static if (is(Key U : U[]))
return hashOf(key, 0); return .hashOf(key, 0);
else else
return hashOf((&key)[0 .. 1], 0); return .hashOf((&key)[0 .. 1], 0);
} }
@property hash_t mask() const @property hash_t mask() const
......
/**
* The default hash implementation.
*
* Copyright: Copyright Sean Kelly 2009 - 2016.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Sean Kelly
* Source: $(DRUNTIMESRC src/rt/util/_hash.d)
*/
module rt.util.hash;
version (X86)
version = AnyX86;
version (X86_64)
version = AnyX86;
version (AnyX86)
version = HasUnalignedOps;
@trusted pure nothrow @nogc
size_t hashOf( const(void)[] buf, size_t seed )
{
/*
* This is Paul Hsieh's SuperFastHash algorithm, described here:
* http://www.azillionmonkeys.com/qed/hash.html
* It is protected by the following open source license:
* http://www.azillionmonkeys.com/qed/weblicense.html
*/
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.
version (HasUnalignedOps)
{
if (!__ctfe)
return *cast(ushort*) x;
}
return ((cast(uint) x[1]) << 8) + (cast(uint) x[0]);
}
// NOTE: SuperFastHash normally starts with a zero hash value. The seed
// value was incorporated to allow chaining.
auto data = cast(const(ubyte)*) buf.ptr;
auto len = buf.length;
auto hash = seed;
if ( len == 0 || data is null )
return 0;
int rem = len & 3;
len >>= 2;
for ( ; len > 0; len-- )
{
hash += get16bits( data );
auto tmp = (get16bits( data + 2 ) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2 * ushort.sizeof;
hash += hash >> 11;
}
switch ( rem )
{
case 3: hash += get16bits( data );
hash ^= hash << 16;
hash ^= data[ushort.sizeof] << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits( data );
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
break;
default:
break;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
unittest
{
enum test_str = "Sample string";
size_t hashval = hashOf(test_str, 5);
//import core.stdc.stdio;
//printf("hashval = %lld\n", cast(long)hashval);
if (hashval.sizeof == 4)
assert(hashval == 528740845);
else if (hashval.sizeof == 8)
assert(hashval == 8106800467257150594L);
else
assert(0);
}
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Authors: Kenji Hara * Authors: Kenji Hara
*/ */
module rt.util.typeinfo; module rt.util.typeinfo;
static import core.internal.hash;
template Floating(T) template Floating(T)
if (is(T == float) || is(T == double) || is(T == real)) if (is(T == float) || is(T == double) || is(T == real))
...@@ -32,19 +33,7 @@ if (is(T == float) || is(T == double) || is(T == real)) ...@@ -32,19 +33,7 @@ if (is(T == float) || is(T == double) || is(T == real))
return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1); return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
} }
size_t hashOf(T value) @trusted public alias hashOf = core.internal.hash.hashOf;
{
if (value == 0) // +0.0 and -0.0
value = 0;
static if (is(T == float)) // special case?
return *cast(uint*)&value;
else
{
import rt.util.hash;
return rt.util.hash.hashOf((&value)[0 .. 1], 0);
}
}
} }
template Floating(T) template Floating(T)
if (is(T == cfloat) || is(T == cdouble) || is(T == creal)) if (is(T == cfloat) || is(T == cdouble) || is(T == creal))
...@@ -73,13 +62,7 @@ if (is(T == cfloat) || is(T == cdouble) || is(T == creal)) ...@@ -73,13 +62,7 @@ if (is(T == cfloat) || is(T == cdouble) || is(T == creal))
return result; return result;
} }
size_t hashOf(T value) @trusted public alias hashOf = core.internal.hash.hashOf;
{
if (value == 0 + 0i)
value = 0 + 0i;
import rt.util.hash;
return rt.util.hash.hashOf((&value)[0 .. 1], 0);
}
} }
template Array(T) template Array(T)
...@@ -118,13 +101,7 @@ if (is(T == float) || is(T == double) || is(T == real) || ...@@ -118,13 +101,7 @@ if (is(T == float) || is(T == double) || is(T == real) ||
return 0; return 0;
} }
size_t hashOf(T[] value) public alias hashOf = core.internal.hash.hashOf;
{
size_t h = 0;
foreach (e; value)
h += Floating!T.hashOf(e);
return h;
}
} }
version (unittest) version (unittest)
...@@ -247,7 +224,7 @@ unittest ...@@ -247,7 +224,7 @@ unittest
{ {
assert(f1 == 0 + 0i); assert(f1 == 0 + 0i);
assert(f1 == f2); assert(f1 == f2);
assert(f1 !is f2); assert(f1 !is f2);
ti = typeid(F); ti = typeid(F);
assert(ti.getHash(&f1) == ti.getHash(&f2)); assert(ti.getHash(&f1) == ti.getHash(&f2));
......
# Copyright (C) 2018 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
load_lib libphobos-dg.exp
# Initialize dg.
dg-init
# Gather a list of all tests.
set tests [lsort [find $srcdir/$subdir *.d]]
# Main loop.
dg-runtest $tests "" $DEFAULT_DFLAGS
# All done.
dg-finish
# Copyright (C) 2018 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
load_lib libphobos-dg.exp
# Initialize dg.
dg-init
# Gather a list of all tests.
set tests [lsort [find $srcdir/$subdir *.d]]
# Main loop.
dg-runtest $tests "" $DEFAULT_DFLAGS
# All done.
dg-finish
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment