Request: Inject std::hash for Uuid type


#1

I have noticed that JUCE is now injecting a std::hash for juce::String. This is useful and allows us to remove our own version.

It would be useful to have this work with Uuids too. This could then be extended for use in JUCE HashMaps too. Maybe something like the following?

int Uuid::hashCode ()
{
    int a = ByteOrder::bigEndianInt(&uuid[0]);
    int b = ByteOrder::bigEndianInt(&uuid[4]);
    int c = ByteOrder::bigEndianInt(&uuid[8]);
    int d = ByteOrder::bigEndianInt(&uuid[12]);

    return a ^ b ^ c ^ d;
}

uint64_t Uuid::hashCode64 ()
{
    uint64_t a = ByteOrder::bigEndianInt64(&uuid[0]);
    uint64_t b = ByteOrder::bigEndianInt64(&uuid[8]);

    return a ^ b;
}

size_t Uuid::hash()
{
#if JUCE_64BIT
    return hashCode64();
#else
    return hashCode();
#endif
}

and

#if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS && ! DOXYGEN // just used to avoid compiling this under compilers that lack libc++
namespace std
{
    template <> struct hash<juce::Uuid>
    {
        size_t operator() (const juce::Uuid& u) const noexcept { return u.hash(); }
    };
}
#endif

and in juce_HashMap.h (DefaultHashFunctions)

static int generateHash (const Uuid& key, int upperLimit) noexcept { return generateHash ((uint32) key.hashCode(), upperLimit); }

#2

Thanks Harry, good suggestion, I’ll sort that out…


#3

The issue is that the C++ committee didn’t implement Boost way of extending std::hash. And you should not do that yourself :confused: Use an explicit std::unordered_map<Uuid, xxx, UuidHash> instead, that’s what we are supposed to do.


#4

http://en.cppreference.com/w/cpp/language/extending_std

Really? I haven’t read the standard but it is mentioned here.


#5

Indeed, I should have read this before… Good then!