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); }