https://issues.dlang.org/show_bug.cgi?id=16269
--- Comment #9 from Ketmar Dark <[email protected]> --- so here is the fixed patch, and new tests: ======================================= diff --git a/src/object.d b/src/object.d index 40e2391..5ac132c 100644 --- a/src/object.d +++ b/src/object.d @@ -1876,6 +1876,7 @@ extern (C) inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow; void* _aaRehash(void** pp, in TypeInfo keyti) pure nothrow; void _aaClear(void* p) pure nothrow; + void _aaEnsureAllocated(void* p, const TypeInfo_AssociativeArray ti); // alias _dg_t = extern(D) int delegate(void*); // int _aaApply(void* aa, size_t keysize, _dg_t dg); @@ -1919,6 +1920,25 @@ void clear(T : Value[Key], Value, Key)(T* aa) _aaClear(*cast(void **) aa); } +T ensureAllocated(T : Value[Key], Value, Key)(ref T aa) +{ + _aaEnsureAllocated(cast(void*)&aa, typeid(T)); + return aa; +} + +T ensureAllocated(T : Value[Key], Value, Key)(T* aa) +{ + if (aa !is null) + { + _aaEnsureAllocated(cast(void*)aa, typeid(T)); + return *aa; + } + else + { + return T.init; // we have to return something here + } +} + T rehash(T : Value[Key], Value, Key)(T aa) { _aaRehash(cast(void**)&aa, typeid(Value[Key])); diff --git a/src/rt/aaA.d b/src/rt/aaA.d index cf8943e..48194b0 100644 --- a/src/rt/aaA.d +++ b/src/rt/aaA.d @@ -443,6 +443,15 @@ extern (C) void _aaClear(AA aa) pure nothrow } } +/// Allocate new AA implementation if it isn't allocated yet. +extern (C) void _aaEnsureAllocated(AA* paa, const TypeInfo_AssociativeArray ti) +{ + if (paa.impl is null) + { + paa.impl = new Impl(ti); + } +} + /// Rehash AA extern (C) void* _aaRehash(AA* paa, in TypeInfo keyti) pure nothrow { -- 2.9.0 ======================================= unittest { void test (string[int] aa) { aa[42] = "42"; } // inline { string[int] aa; test(aa.ensureAllocated); assert(aa[42] == "42"); // check that AA is not cleared aa.ensureAllocated(); assert(aa[42] == "42"); } // function { string[int] bb; bb.ensureAllocated; test(bb); assert(bb[42] == "42"); // check that AA is not cleared bb.ensureAllocated(); assert(bb[42] == "42"); } } // test pointer version unittest { void test (string[int] aa) { aa[42] = "42"; } // inline { string[int] aa; string[int]* ptr = &aa; test(ptr.ensureAllocated); assert(aa[42] == "42"); // check that AA is not cleared ptr.ensureAllocated(); assert(aa[42] == "42"); } // case of "null pointer" { string[int]* bb; test(bb.ensureAllocated); // this should not fail } } --
