Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 10 additions & 15 deletions src/core/internal/hash.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,21 @@ module core.internal.hash;
import core.internal.convert;

//enum hash. CTFE depends on base type
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (is(T == enum) || is(T == typedef))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (is(T == enum))
{
static if (is(T EType == enum)) //for EType
{
EType e_val = cast(EType)val;
return hashOf(e_val, seed);
}
else static if (is(T TDType == typedef)) //for EType
{
TDType td_val = cast(TDType)val;
return hashOf(td_val, seed);
}
else
{
static assert(0);
}
}

//CTFE ready (depends on base type). Can be merged with dynamic array hash
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && __traits(isStaticArray, T))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && __traits(isStaticArray, T))
{
size_t cur_hash = seed;
foreach (ref cur; val)
Expand All @@ -42,7 +37,7 @@ size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T ==
}

//dynamic array hash
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && !is(T : typeof(null)) && is(T S: S[]) && !__traits(isStaticArray, T))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T : typeof(null)) && is(T S: S[]) && !__traits(isStaticArray, T))
{
alias ElementType = typeof(val[0]);
static if (is(ElementType == interface) || is(ElementType == class) ||
Expand Down Expand Up @@ -72,7 +67,7 @@ size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T ==

//arithmetic type hash
@trusted nothrow pure
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && __traits(isArithmetic, T))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && __traits(isArithmetic, T))
{
static if(__traits(isFloating, val))
{
Expand All @@ -89,14 +84,14 @@ size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T ==

//typeof(null) hash. CTFE supported
@trusted nothrow pure
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && is(T : typeof(null)))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && is(T : typeof(null)))
{
return hashOf(cast(void*)null);
}

//Pointers hash. CTFE unsupported if not null
@trusted nothrow pure
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && is(T V : V*) && !is(T : typeof(null)))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && is(T V : V*) && !is(T : typeof(null)))
{
if(__ctfe)
{
Expand All @@ -114,7 +109,7 @@ size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T ==
}

//struct or union hash
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && (is(T == struct) || is(T == union)))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && (is(T == struct) || is(T == union)))
{
static if (is(typeof(val.toHash()) == size_t)) //CTFE depends on toHash()
{
Expand Down Expand Up @@ -143,21 +138,21 @@ size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T ==

//delegate hash. CTFE unsupported
@trusted nothrow pure
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && is(T == delegate))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && is(T == delegate))
{
assert(!__ctfe, "unable to compute hash of "~T.stringof);
const(ubyte)[] bytes = (cast(const(ubyte)*)&val)[0 .. T.sizeof];
return bytesHash(bytes.ptr, bytes.length, seed);
}

//class or interface hash. CTFE depends on toHash
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && is(T == interface) || is(T == class))
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && is(T == interface) || is(T == class))
{
return mixHash(val ? (cast(Object)val).toHash() : 0, seed);
}

//associative array hash. CTFE depends on base types
size_t hashOf(T)(auto ref T aa, size_t seed = 0) if (!is(T == enum) && !is(T == typedef) && __traits(isAssociativeArray, T))
size_t hashOf(T)(auto ref T aa, size_t seed = 0) if (!is(T == enum) && __traits(isAssociativeArray, T))
{
try
{
Expand Down