On 10/31/2016 12:08 PM, Gary Willoughby wrote:
Can someone please explain why the following assertion fails?

import std.stdio;
import std.conv;

void main(string[] args)
{
    auto x = 1;

    assert(hashOf(x.to!(string)) == hashOf(x.to!(string)));
}

Thanks.

Because it considers the .ptr property of arrays as well:


https://github.com/dlang/druntime/blob/master/src/core/internal/hash.d#L61

//dynamic array hash
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)
    && !is(T == struct) && !is(T == class) && !is(T == union))
{
    alias ElementType = typeof(val[0]);
    static if (is(ElementType == interface) || is(ElementType == class) ||
                   ((is(ElementType == struct) || is(ElementType == union))
                       && is(typeof(val[0].toHash()) == size_t)))
//class or interface array or struct array with toHash(); CTFE depend on toHash() method
    {
        size_t hash = seed;
        foreach (o; val)
        {
            hash = hashOf(o, hash);
        }
        return hash;
    }
    else static if (is(typeof(toUbyte(val)) == const(ubyte)[]))
//ubyteble array (arithmetic types and structs without toHash) CTFE ready for arithmetic types and structs without reference fields
    {
        auto bytes = toUbyte(val);
        return bytesHash(bytes.ptr, bytes.length, seed);    // <-- HERE
    }
    else //Other types. CTFE unsupported
    {
        assert(!__ctfe, "unable to compute hash of "~T.stringof);
        return bytesHash(val.ptr, ElementType.sizeof*val.length, seed);
    }
}

Ali

Reply via email to