[Issue 16269] add `aa.ensureAllocated` method to associative array to clear and initialize it

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Wed Jul 13 10:46:47 PDT 2016


https://issues.dlang.org/show_bug.cgi?id=16269

--- Comment #9 from Ketmar Dark <ketmar at ketmar.no-ip.org> ---
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
  }
}

--


More information about the Digitalmars-d-bugs mailing list