Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2238 from n8sh/core-hash-19048
Browse files Browse the repository at this point in the history
Fix Issue 19048 - In core.internal.hash.hashOf reduce template bloat: remove `auto ref` where unneeded and add `const` where possible
merged-on-behalf-of: Steven Schveighoffer <schveiguy@users.noreply.github.com>
  • Loading branch information
dlang-bot committed Jul 3, 2018
2 parents 707d703 + c819624 commit b5d124a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 18 deletions.
18 changes: 9 additions & 9 deletions src/core/internal/convert.d
Expand Up @@ -34,7 +34,7 @@ private ubyte[] ctfe_alloc()(size_t n)
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(ref T val) if(is(Unqual!T == float) || is(Unqual!T == double) || is(Unqual!T == real) ||
const(ubyte)[] toUbyte(T)(const ref T val) if(is(Unqual!T == float) || is(Unqual!T == double) || is(Unqual!T == real) ||
is(Unqual!T == ifloat) || is(Unqual!T == idouble) || is(Unqual!T == ireal))
{
static const(ubyte)[] reverse_(const(ubyte)[] arr)
Expand Down Expand Up @@ -286,7 +286,7 @@ private ulong shiftrRound(ulong x)
}

@safe pure nothrow @nogc
private uint binLog2(T)(T x)
private uint binLog2(T)(const T x)
{
assert(x > 0);
int max = 2 ^^ (FloatTraits!T.EXPONENT-1)-1;
Expand Down Expand Up @@ -499,13 +499,13 @@ template floatFormat(T) if(is(T:real) || is(T:ireal))

// all toUbyte functions must be evaluable at compile time
@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(T[] arr) if (T.sizeof == 1)
const(ubyte)[] toUbyte(T)(const T[] arr) if (T.sizeof == 1)
{
return cast(const(ubyte)[])arr;
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(T[] arr) if ((is(typeof(toUbyte(arr[0])) == const(ubyte)[])) && (T.sizeof > 1))
const(ubyte)[] toUbyte(T)(const T[] arr) if ((is(typeof(toUbyte(arr[0])) == const(ubyte)[])) && (T.sizeof > 1))
{
if (__ctfe)
{
Expand All @@ -525,7 +525,7 @@ const(ubyte)[] toUbyte(T)(T[] arr) if ((is(typeof(toUbyte(arr[0])) == const(ubyt
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(ref T val) if (__traits(isIntegral, T) && !is(T == enum))
const(ubyte)[] toUbyte(T)(const ref T val) if (__traits(isIntegral, T) && !is(T == enum))
{
static if (T.sizeof == 1)
{
Expand Down Expand Up @@ -561,7 +561,7 @@ const(ubyte)[] toUbyte(T)(ref T val) if (__traits(isIntegral, T) && !is(T == enu
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(ref T val) if (is(Unqual!T == cfloat) || is(Unqual!T == cdouble) ||is(Unqual!T == creal))
const(ubyte)[] toUbyte(T)(const ref T val) if (is(Unqual!T == cfloat) || is(Unqual!T == cdouble) ||is(Unqual!T == creal))
{
if (__ctfe)
{
Expand All @@ -581,12 +581,12 @@ const(ubyte)[] toUbyte(T)(ref T val) if (is(Unqual!T == cfloat) || is(Unqual!T =
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(ref T val) if (is(T V == enum) && is(typeof(toUbyte(cast(V)val)) == const(ubyte)[]))
const(ubyte)[] toUbyte(T)(const ref T val) if (is(T V == enum) && is(typeof(toUbyte(cast(const V)val)) == const(ubyte)[]))
{
if (__ctfe)
{
static if (is(T V == enum)){}
return toUbyte(cast(V) val);
return toUbyte(cast(const V) val);
}
else
{
Expand Down Expand Up @@ -649,7 +649,7 @@ private bool isNonReferenceStruct(T)() if (is(T == struct) || is(T == union))
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(ref T val) if (is(T == struct) || is(T == union))
const(ubyte)[] toUbyte(T)(const ref T val) if (is(T == struct) || is(T == union))
{
if (__ctfe)
{
Expand Down
19 changes: 10 additions & 9 deletions src/core/internal/hash.d
Expand Up @@ -56,7 +56,7 @@ size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && __traits
}

//dynamic array hash
size_t hashOf(T)(auto ref T val, size_t seed = 0)
size_t hashOf(T)(T val, size_t seed = 0)
if (!is(T == enum) && !is(T : typeof(null)) && is(T S: S[]) && !__traits(isStaticArray, T)
&& !is(T == struct) && !is(T == class) && !is(T == union))
{
Expand Down Expand Up @@ -101,13 +101,14 @@ if (!is(T == enum) && !is(T : typeof(null)) && is(T S: S[]) && !__traits(isStati

//arithmetic type hash
@trusted @nogc nothrow pure
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && __traits(isArithmetic, T))
size_t hashOf(T)(scope const T val, size_t seed = 0) if (!is(T == enum) && __traits(isArithmetic, T))
{
static if(__traits(isFloating, val))
{
static if (floatCoalesceZeroes || floatCoalesceNaNs)
{
auto data = val;
import core.internal.traits : Unqual;
Unqual!T data = val;
// Zero coalescing not supported for deprecated complex types.
static if (floatCoalesceZeroes && is(typeof(data = 0)))
if (data == 0) data = 0; // +0.0 and -0.0 become the same.
Expand Down Expand Up @@ -170,14 +171,14 @@ size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && __traits

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

//Pointers hash. CTFE unsupported if not null
@trusted @nogc nothrow pure
size_t hashOf(T)(auto ref T val, size_t seed = 0)
size_t hashOf(T)(scope const T val, size_t seed = 0)
if (!is(T == enum) && is(T V : V*) && !is(T : typeof(null))
&& !is(T == struct) && !is(T == class) && !is(T == union))
{
Expand Down Expand Up @@ -256,21 +257,21 @@ nothrow pure @safe unittest // issue 19005

//delegate hash. CTFE unsupported
@trusted @nogc nothrow pure
size_t hashOf(T)(auto ref T val, size_t seed = 0) if (!is(T == enum) && is(T == delegate))
size_t hashOf(T)(scope const 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 bytesHashAlignedBy!T(bytes, 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 == interface) || is(T == class))
size_t hashOf(T)(T val, size_t seed = 0) if (!is(T == enum) && is(T == interface) || is(T == class))
{
return hashOf(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) && __traits(isAssociativeArray, T))
size_t hashOf(T)(T aa, size_t seed = 0) if (!is(T == enum) && __traits(isAssociativeArray, T))
{
if (!aa.length) return hashOf(0, seed);
size_t h = 0;
Expand Down Expand Up @@ -544,7 +545,7 @@ nothrow pure @system unittest // issue 18918

// This overload is for backwards compatibility.
@system pure nothrow @nogc
size_t bytesHash(const(void)* buf, size_t len, size_t seed)
size_t bytesHash(scope const(void)* buf, size_t len, size_t seed)
{
return bytesHashAlignedBy!ubyte((cast(const(ubyte)*) buf)[0 .. len], seed);
}
Expand Down

0 comments on commit b5d124a

Please sign in to comment.