On 03/23/2012 10:07 PM, Timon Gehr wrote:

I see. An alternative solution (one that does not make AAs depend on
Phobos and is more slick) would be to use the const qualified key type
for lookup (that is what const is for) and to have immutable keys for
stores. For types that define .idup, there would be another overload of
opIndexAssign that can take a const qualified key.

Proof of concept:

// ctfe-able simple and stupid replace
string replace(string str, string from, string to){
        string r = "";
        foreach(i; 0..str.length){
                if(i+from.length<=str.length &&
                   str[i..i+from.length]==from){
                        r~=to;
                        i+=from.length-1;
                }else r~=str[i];
        }
        return r;
}

template getConstQual(T){ // hack
        static if(is(T==string)) alias const(char)[] getConstQual;
        else alias const(typeof(mixin(`(`~T.stringof.
          replace("immutable","const")~`).init`))) getConstQual;
}

int numidup = 0;

struct AA(Key, Value) if(is(Key:immutable(Key))){
        Value[Key] payload;
        auto opIndex(getConstQual!Key k){return payload[cast(immutable)k];}
        auto opIndexAssign(Value v, Key k){return payload[cast(immutable)k]=v;}
        static if(is(typeof(getConstQual!Key.init.idup))){
                auto opIndexAssign(Value v, getConstQual!Key k){
                        if(auto p = (cast(immutable)k) in payload) return *p=v;
                        numidup++;
                        return payload[k.idup]=v;
                }
        }
}

void main() {
        AA!(string, int) aa;
        aa["123"] = 123;
        char[3] ch = "123";
        assert(aa[ch] == 123);
        ch[1]='3';
        assert(numidup == 0);
        aa[ch]=133;
        assert(numidup == 1);
        assert(aa["133"]==133);
        ch[0]='3';
        assert(aa["133"]==133);
        assert(numidup == 1);
}

Reply via email to