[Issue 10821] .byKey erroneously returns a null key

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sat Aug 17 15:15:13 PDT 2013


http://d.puremagic.com/issues/show_bug.cgi?id=10821



--- Comment #11 from hsteoh at quickfur.ath.cx 2013-08-17 15:15:12 PDT ---
Sorry, I mistakenly thought you were talking about std.container. :-/

Anyway, looking over the dcollections code, I'm pretty impressed to realize
that foreach can take function pointers?! That's something I've never knew
before!

In any case, purge is basically a restricted form of container modification
while iterating -- it iterates over the elements and lets you decide whether or
not to remove each one. This is a more controlled form of container
modification during iteration, and is made safe by (1) (implicitly) caching the
reference to the next element and not advancing the iterator if the element
*was* elected to be removed, and (2) only allowing the current element to be
removed, not any arbitrary element. If you relax (2), say your foreach body
directly references the container and deletes random elements, then all hell
breaks loose. If you enforce (2), then you can use (1) as implementation
strategy to allow deletion during iteration.

So one possibility in the case of your signal/slot code, is to have the
delegate return a bool/flag to indicate whether to remove itself from the
table. That way, you can avoid keeping lists of what to remove after the
iteration. It won't be as nice as a foreach loop, though, since you have to
manually control where your iterator is:

    auto r = aa.byKey;
    while (!r.empty) {
        auto key = r.front;
        auto dg = aa[key];
        bool deleteDg = dg(args) == Flag.deleteMe;
        r.popFront(); // important: this must come before aa.remove(key)
        if (deleteDg == Flag.deleteMe) {
            aa.remove(key);
        }
    }

By advancing the range before the aa.remove(key) call and only allowing the
current element to be deleted, you avoid running into invalid pointers.

This doesn't address the problem with dg inserting new things into aa, though,
since the newly inserted entry may or may not get iterated over by the loop
depending on where its hash value falls relative to the current position of the
byKey range. So there's still some unpredictability there.

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


More information about the Digitalmars-d-bugs mailing list