www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 10046] New: Wrong insertion of Tuple in associative array

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10046

           Summary: Wrong insertion of Tuple in associative array
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



import std.stdio: writeln;
import std.typecons: Tuple;
void main () {
    alias Foo = Tuple!string;
    int[Foo] aa;
    auto ka = Foo("foo".idup);
    aa[ka] = 1;
    auto kb = Foo("foo".idup);
    aa[kb] = 2;
    aa.writeln;
}


Output dmd 2.063beta:

[Tuple!(string)("foo"):1, Tuple!(string)("foo"):2]


Expected output:

[Tuple!(string)("foo"):2]

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 08 2013
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10046


joanbrugueram gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |joanbrugueram gmail.com



Very annoying bug since it basically kills "multiindexing" using associative
arrays. As far as I know it's simply because Tuple hasn't implemented toHash.

It can be worked around by using an structure with a toHash function (WARNING:
The documentation on associative arrays says it's called opHash. It's called
toHash!).

Here's my drop-in replacement for 2-tuples. Feel free to use it freely for
whatever you want. It works in my (string, string) case but I haven't tested it
for other types, but it should work.

****

// Workaround for http://d.puremagic.com/issues/show_bug.cgi?id=10046
static struct MyTuple(A, B)
{
    private A first;
    private B second;
    auto ref opIndex(size_t index)
    {
        switch (index)
        {
            case 0: return first;
            case 1: return second;
            default: assert(0);
        }
    }
    const hash_t toHash()
    {
        return typeid(A).getHash(&first) ^ typeid(B).getHash(&second);
    }
    const bool opEquals(ref const MyTuple!(A, B) s)
    {
        return first == s.first && second == s.second;
    }
    const int opCmp(ref const MyTuple!(A, B) s)
    {
        if (first != s.first)
            return (first < s.first) ? -1 : 1;
        if (second != s.second)
            return (second < s.second) ? -1 : 1;
        return 0;
    }
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 27 2013