core.internal.hash

Written in the D programming language. This module provides functions to uniform calculating hash values for different types

Types 1

private aliassmallBytesHash = fnv

Functions 29

fnsize_t hashOf(T)(auto ref T val, size_t seed = 0) if (is(T == enum) && !__traits(isScalar, T))
fnsize_t hashOf(T)(scope const auto ref T val, size_t seed = 0) if (!is(T == enum) && __traits(isStaticArray, T) && canBitwiseHash!T)
fnsize_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && __traits(isStaticArray, T) && !canBitwiseHash!T)
fnsize_t hashOf(T)(scope const T val, size_t seed = 0) if (is(T == S[], S) && (__traits(isScalar, S) || canBitwiseHash!S))
fnsize_t hashOf(T)(T val, size_t seed = 0) if (is(T == S[], S) && !(__traits(isScalar, S) || canBitwiseHash!S))
private fnF coalesceFloat(F)(const F val) if (__traits(isFloating, val) && !is(F == __vector) && !is(F : creal))
fnsize_t hashOf(T)(scope const T val) if (__traits(isScalar, T) && !is(T == __vector)) @trusted @nogc nothrow pure
fnsize_t hashOf(T)(scope const T val, size_t seed) if (__traits(isScalar, T) && !is(T == __vector)) @trusted @nogc nothrow pure
fnsize_t hashOf(T)(scope const T val, size_t seed = 0) if (is(T == __vector)) @safe @nogc nothrow pure
fnsize_t hashOf(T)(scope const T val) if (!is(T == enum) && is(T : typeof(null))) @trusted @nogc nothrow pure
fnsize_t hashOf(T)(scope const T val, size_t seed) if (!is(T == enum) && is(T : typeof(null))) @trusted @nogc nothrow pure
fnsize_t hashOf(T)(scope const auto ref T val, size_t seed = 0) if (!is(T == enum) && (is(T == struct) || is(T == union)) && !is(T == const) && !is(T == immutable) && canBitwiseHash!T)
fnsize_t hashOf(T)(auto ref T val) if (!is(T == enum) && (is(T == struct) || is(T == union)) && !canBitwiseHash!T)
fnsize_t hashOf(T)(auto ref T val, size_t seed) if (!is(T == enum) && (is(T == struct) || is(T == union)) && !canBitwiseHash!T)
fnsize_t hashOf(T)(scope auto ref T val, size_t seed = 0) if (!is(T == enum) && (is(T == struct) || is(T == union)) && (is(T == const) || is(T == immutable)) && canBitwiseHash!T && !canBitwiseHash!(Unconst!T))
fnsize_t hashOf(T)(scope const T val, size_t seed = 0) if (!is(T == enum) && is(T == delegate)) @trusted @nogc nothrow pure
fnsize_t hashOf(T)(scope const T val) if (!is(T == enum) && (is(T == interface) || is(T == class)) && canBitwiseHash!T) @nogc nothrow pure @trusted
fnsize_t hashOf(T)(scope const T val, size_t seed) if (!is(T == enum) && (is(T == interface) || is(T == class)) && canBitwiseHash!T) @nogc nothrow pure @trusted
fnsize_t hashOf(T)(T val) if (!is(T == enum) && (is(T == interface) || is(T == class)) && !canBitwiseHash!T)
fnsize_t hashOf(T)(T val, size_t seed) if (!is(T == enum) && (is(T == interface) || is(T == class)) && !canBitwiseHash!T)
fnsize_t hashOf(T)(T aa) if (!is(T == enum) && __traits(isAssociativeArray, T))
fnsize_t hashOf(T)(T aa, size_t seed) if (!is(T == enum) && __traits(isAssociativeArray, T))
fnsize_t bytesHash()(scope const(void) * buf, size_t len, size_t seed) @system pure nothrow @nogc
private fnsize_t fnv()(scope const(ubyte)[] bytes, size_t seed) @nogc nothrow pure @safe
private fnuint get32bits()(scope const(ubyte) * x) @nogc nothrow pure @system
private fnsize_t _bytesHash(bool dataKnownToBeAligned)(scope const(ubyte)[] bytes, size_t seed) @nogc nothrow pure @trusted
private fnsize_t _bytesHashAligned(scope const(ubyte)[] bytes, size_t seed) @nogc nothrow pure @trusted
private fnsize_t _bytesHashUnaligned(scope const(ubyte)[] bytes, size_t seed) @nogc nothrow pure @trusted
private fnsize_t bytesHash(bool dataKnownToBeAligned)(scope const(ubyte)[] bytes, size_t seed) @nogc nothrow pure @trusted

Variables 3

private enumvarfloatCoalesceZeroes = true
private enumvarfloatCoalesceNaNs = true
private enumvar_hashOfStruct = q{ enum bool isChained = is(typeof(seed) : size_t); static if (!isChained) enum size_t seed = 0; static if (hasCallableToHash!(typeof(val))) //CTFE depends on toHash() { static if (!__traits(isSame, typeof(val), __traits(parent, val.toHash)) && is(typeof(val is null))) { static if (isChained) return hashOf(__traits(getMember, val, __traits(getAliasThis, typeof(val))), seed); else return hashOf(__traits(getMember, val, __traits(getAliasThis, typeof(val)))); } else { static if (isChained) return hashOf(cast(size_t) val.toHash(), seed); else return val.toHash(); } } else { import core.internal.convert : toUbyte; static if (__traits(hasMember, T, "toHash") && is(typeof(T.toHash) == function)) { // TODO: in the future maybe this should be changed to a static // assert(0), because if there's a `toHash` the programmer probably // expected it to be called and a compilation failure here will // expose a bug in his code. // In the future we also might want to disallow non-const toHash // altogether. pragma(msg, "Warning: struct "~__traits(identifier, T) ~" has method toHash, however it cannot be called with " ~typeof(val).stringof~" this."); static if (__traits(compiles, __traits(getLocation, T.toHash))) { enum file = __traits(getLocation, T.toHash)[0]; enum line = __traits(getLocation, T.toHash)[1].stringof; pragma(msg, " ",__traits(identifier, T),".toHash defined here: ",file,"(",line,")"); } } static if (T.tupleof.length == 0) { return seed; } else static if ((is(T == struct) && !canBitwiseHash!T) || T.tupleof.length == 1) { static if (isChained) size_t h = seed; static foreach (i, F; typeof(val.tupleof)) { static if (__traits(isStaticArray, F)) { static if (i == 0 && !isChained) size_t h = 0; static if (F.sizeof > 0 && canBitwiseHash!F) // May use smallBytesHash instead of bytesHash. h = bytesHashWithExactSizeAndAlignment!F(toUbyte(val.tupleof[i]), h); else // We can avoid the "double hashing" the top-level version uses // for consistency with TypeInfo.getHash. foreach (ref e; val.tupleof[i]) h = hashOf(e, h); } else static if (is(F == struct) || is(F == union)) { static if (hasCallableToHash!F) { static if (!__traits(isSame, F, __traits(parent, val.tupleof[i].toHash)) && is(typeof(val.tupleof[i] is null))) { static if (i == 0 && !isChained) size_t h = hashOf(__traits(getMember, val.tupleof[i], __traits(getAliasThis, F))); else h = hashOf(__traits(getMember, val.tupleof[i], __traits(getAliasThis, F)), h); } else { static if (i == 0 && !isChained) size_t h = val.tupleof[i].toHash(); else h = hashOf(cast(size_t) val.tupleof[i].toHash(), h); } } else static if (F.tupleof.length == 1) { // Handle the single member case separately to avoid unnecessarily using bytesHash. static if (i == 0 && !isChained) size_t h = hashOf(val.tupleof[i].tupleof[0]); else h = hashOf(val.tupleof[i].tupleof[0], h); } else static if (canBitwiseHash!F) { // May use smallBytesHash instead of bytesHash. static if (i == 0 && !isChained) size_t h = 0; h = bytesHashWithExactSizeAndAlignment!F(toUbyte(val.tupleof[i]), h); } else { // Nothing special happening. static if (i == 0 && !isChained) size_t h = hashOf(val.tupleof[i]); else h = hashOf(val.tupleof[i], h); } } else { // Nothing special happening. static if (i == 0 && !isChained) size_t h = hashOf(val.tupleof[i]); else h = hashOf(val.tupleof[i], h); } } return h; } else static if (is(typeof(toUbyte(val)) == const(ubyte)[]))//CTFE ready for structs without reference fields { // Not using bytesHashWithExactSizeAndAlignment here because // the result may differ from typeid(T).hashOf(&val). return bytesHashAlignedBy!T(toUbyte(val), seed); } else // CTFE unsupported { assert(!__ctfe, "unable to compute hash of "~T.stringof~" at compile time"); const(ubyte)[] bytes = (() @trusted => (cast(const(ubyte)*)&val)[0 .. T.sizeof])(); // Not using bytesHashWithExactSizeAndAlignment here because // the result may differ from typeid(T).hashOf(&val). return bytesHashAlignedBy!T(bytes, seed); } } }

Templates 4

tmplisCppClassWithoutHash(T)
tmplcanBitwiseHash(T)
tmplbytesHashAlignedBy(AlignType)
tmplbytesHashWithExactSizeAndAlignment(SizeAndAlignType)