From fc2f92785aa98b095590184785fe649740c5e7e8 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Sat, 2 Mar 2019 12:24:30 +0000 Subject: [PATCH 1/3] Fix Issue 10535 - Add AA initialize function --- changelog/aa-init.dd | 18 ++++++++++++++++++ src/object.d | 38 ++++++++++++++++++++++++++++++++++++++ src/rt/aaA.d | 6 ++++++ 3 files changed, 62 insertions(+) create mode 100644 changelog/aa-init.dd diff --git a/changelog/aa-init.dd b/changelog/aa-init.dd new file mode 100644 index 0000000000..333c608c34 --- /dev/null +++ b/changelog/aa-init.dd @@ -0,0 +1,18 @@ +Added `initialize` function for associative arrays + +This function allocates memory for an empty associative array (AA). It +is useful to avoid copying a null AA reference. Then +when AA elements are added through the original reference, the copied +reference will still point to the same AA: +--- +int[int] aa; +auto b = aa; +assert(b is null); +aa.initialize; +assert(aa !is null); +auto c = aa; + +aa[4] = 4; +assert(b != aa); +assert(c is aa); +--- diff --git a/src/object.d b/src/object.d index 4bbfe3bc1f..4e54b7524c 100644 --- a/src/object.d +++ b/src/object.d @@ -3024,6 +3024,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 _aaInitialize(void* p, const TypeInfo_AssociativeArray ti); // alias _dg_t = extern(D) int delegate(void*); // int _aaApply(void* aa, size_t keysize, _dg_t dg); @@ -3057,10 +3058,47 @@ void* aaLiteral(Key, Value)(Key[] keys, Value[] values) @trusted pure alias AssociativeArray(Key, Value) = Value[Key]; +/*********************************** + * Allocate memory for an empty associative array. + * This is useful to avoid copying a null reference when each reference + * should point to the same associative array data. + * Without using this function, an associative array is initialized only + * when the first element is added. + * Params: + * aa = The associative array. + * See_Also: $(LREF clear) + */ +void initialize(T : Value[Key], Value, Key)(ref T aa) @trusted +{ + _aaInitialize(cast(void*) &aa, typeid(T)); +} + +/// +@safe unittest +{ + int[int] aa; + auto b = aa; + assert(b is null); + aa.initialize; + assert(aa !is null); + auto c = aa; + + aa[4] = 4; + assert(b != aa); + assert(c is aa); +} + +/* ditto */ +void initialize(T : Value[Key], Value, Key)(T* aa) @safe +{ + _aaInitialize(*cast(void**) aa, typeid(T)); +} + /*********************************** * Removes all remaining keys and values from an associative array. * Params: * aa = The associative array. + * See_Also: $(LREF initialize) */ void clear(T : Value[Key], Value, Key)(T aa) { diff --git a/src/rt/aaA.d b/src/rt/aaA.d index 08dd932df9..5b221b27cb 100644 --- a/src/rt/aaA.d +++ b/src/rt/aaA.d @@ -640,6 +640,12 @@ extern (C) void _aaClear(AA aa) pure nothrow } } +/// Allocate new AA implementation. +extern (C) void _aaInitialize(AA* paa, const TypeInfo_AssociativeArray ti) +{ + paa.impl = new Impl(ti); +} + /// Rehash AA extern (C) void* _aaRehash(AA* paa, in TypeInfo keyti) pure nothrow { From ef6b73bb2f1896f8c0b97290664794d893c3a603 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Sat, 2 Mar 2019 17:08:58 +0000 Subject: [PATCH 2/3] Fix initialize(AA*) --- src/object.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object.d b/src/object.d index 4e54b7524c..96bc4dd043 100644 --- a/src/object.d +++ b/src/object.d @@ -3091,7 +3091,7 @@ void initialize(T : Value[Key], Value, Key)(ref T aa) @trusted /* ditto */ void initialize(T : Value[Key], Value, Key)(T* aa) @safe { - _aaInitialize(*cast(void**) aa, typeid(T)); + _aaInitialize(cast(void*) aa, typeid(T)); } /*********************************** From b95457e47b4018a30af37afc57b05c06757d63a1 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Mon, 4 Mar 2019 13:46:58 +0000 Subject: [PATCH 3/3] fix line endings --- changelog/aa-init.dd | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/changelog/aa-init.dd b/changelog/aa-init.dd index 333c608c34..c736ab2baf 100644 --- a/changelog/aa-init.dd +++ b/changelog/aa-init.dd @@ -1,18 +1,18 @@ -Added `initialize` function for associative arrays - -This function allocates memory for an empty associative array (AA). It -is useful to avoid copying a null AA reference. Then -when AA elements are added through the original reference, the copied -reference will still point to the same AA: ---- -int[int] aa; -auto b = aa; -assert(b is null); -aa.initialize; -assert(aa !is null); -auto c = aa; - -aa[4] = 4; -assert(b != aa); -assert(c is aa); ---- +Added `initialize` function for associative arrays + +This function allocates memory for an empty associative array (AA). It +is useful to avoid copying a null AA reference. Then +when AA elements are added through the original reference, the copied +reference will still point to the same AA: +--- +int[int] aa; +auto b = aa; +assert(b is null); +aa.initialize; +assert(aa !is null); +auto c = aa; + +aa[4] = 4; +assert(b != aa); +assert(c is aa); +---