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

Commit

Permalink
comment and unittest for move of AA literal keys&values
Browse files Browse the repository at this point in the history
- also destroy values before overwriting them (due to duplicate keys)
  during literal construction
  • Loading branch information
MartinNowak committed Apr 21, 2015
1 parent 2532129 commit a554721
Showing 1 changed file with 56 additions and 2 deletions.
58 changes: 56 additions & 2 deletions src/rt/aaA.d
Expand Up @@ -537,12 +537,17 @@ extern (C) Impl* _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void
{
p = aa.findSlotInsert(hash);
p.hash = hash;
p.entry = allocEntry(aa, pkey);
p.entry = allocEntry(aa, pkey); // move key, no postblit
aa.firstUsed = min(aa.firstUsed, cast(uint)(p - aa.buckets.ptr));
}
else if (aa.entryTI && hasDtor(ti.value))
{
// destroy existing value before overwriting it
ti.value.destroy(p.entry + off);
}
// set hash and blit value
auto pdst = p.entry + off;
pdst[0 .. valsz] = pval[0 .. valsz];
pdst[0 .. valsz] = pval[0 .. valsz]; // move value, no postblit

pkey += keysz;
pval += valsz;
Expand Down Expand Up @@ -866,3 +871,52 @@ unittest
foreach (i; 6 .. 10)
assert(i in aa);
}

// test postblit for AA literals
unittest
{
static struct T
{
static size_t postblit, dtor;
this(this)
{
++postblit;
}

~this()
{
++dtor;
}
}

T t;
auto aa1 = [0 : t, 1 : t];
assert(T.dtor == 0 && T.postblit == 2);
aa1[0] = t;
assert(T.dtor == 1 && T.postblit == 3);

T.dtor = 0;
T.postblit = 0;

auto aa2 = [0 : t, 1 : t, 0 : t]; // literal with duplicate key, value overwritten
assert(T.dtor == 1 && T.postblit == 3);

T.dtor = 0;
T.postblit = 0;

auto aa3 = [t : 0];
assert(T.dtor == 0 && T.postblit == 1);
aa3[t] = 1;
assert(T.dtor == 0 && T.postblit == 1);
aa3.remove(t);
assert(T.dtor == 0 && T.postblit == 1);
aa3[t] = 2;
assert(T.dtor == 0 && T.postblit == 2);

// dtor will be called by GC finalizers
aa1 = null;
aa2 = null;
aa3 = null;
GC.runFinalizers((cast(char*)(&entryDtor))[0 .. 1]);
assert(T.dtor == 6 && T.postblit == 2);
}

0 comments on commit a554721

Please sign in to comment.