Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Fix Issue 10535 - Add initialize function to allocate an empty AA #2504

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions changelog/aa-init.dd
Original file line number Diff line number Diff line change
@@ -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);
---
38 changes: 38 additions & 0 deletions src/object.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like filling up the object module with a lot of symbols. This is a pretty common name as well.

{
_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)
{
Expand Down
6 changes: 6 additions & 0 deletions src/rt/aaA.d
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down