June 15, 2013
Hi all,

How to implement a proper hash method for a struct/class having as a base one or more floating point?

When I compile with the -w flags, dmd 2.063 tells me that the function must be size_t toHash() const nothrow @safe.

The point is that the nothrow doesn't permit the std.conv.to conversions, while the @safe does not permit the cast().

So how to perform a little math on the floating and then turning the result to a proper integer hash?

Suggestions welcome! Thank!

Paolo Invernizzi
June 15, 2013
On 06/15/2013 03:13 AM, Paolo Invernizzi wrote:
> Hi all,
>
> How to implement a proper hash method for a struct/class having as a
> base one or more floating point?
>
> When I compile with the -w flags, dmd 2.063 tells me that the function
> must be size_t toHash() const nothrow @safe.
>
> The point is that the nothrow doesn't permit the std.conv.to
> conversions, while the @safe does not permit the cast().
>
> So how to perform a little math on the floating and then turning the
> result to a proper integer hash?
>
> Suggestions welcome! Thank!
>
> Paolo Invernizzi

I don't know whether it works correctly, but can you try calling typeid(f).getHash(&f):

import std.stdio;

struct S
{
    float f;
    int i;

    const hash_t toHash() nothrow @safe
    {
        return typeid(f).getHash(&f);
    }
}

void main()
{
    string[S] aa = [ S(0.5) : "half", S(0.25) : "quarter" ];

    aa[S(0.5)] = "one over two";
    aa[S(0.25)] = "one over four";

    writeln(aa);
}

Of course I have used exactly representable values 0.5 and 0.25 instead of any other float value. Maybe you can afford to store such a value (in addition to your actual float value) to be used for hashing.

Ali