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

Commit

Permalink
core.internal.arrray.appending.d: Optimise template _d_arrayappendT
Browse files Browse the repository at this point in the history
Only call `copyEmplace` when `T` has a copy ctor and no postblit.

Signed-off-by: Teodor Dutu <teodor.dutu@gmail.com>
  • Loading branch information
teodutu authored and dlang-bot committed May 27, 2022
1 parent a268ab8 commit f89da31
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/core/internal/array/appending.d
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,35 @@ ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @
import core.internal.traits : hasElaborateCopyConstructor, Unqual;
import core.lifetime : copyEmplace;

enum hasPostblit = __traits(hasPostblit, T);
auto length = x.length;

_d_arrayappendcTXImpl!Tarr._d_arrayappendcTX(x, y.length);

static if (hasElaborateCopyConstructor!T)
// Only call `copyEmplace` if `T` has a copy ctor and no postblit.
static if (hasElaborateCopyConstructor!T && !hasPostblit)
{
foreach (i, ref elem; y)
copyEmplace(elem, x[length + i]);
}
else
{
// blit all elements at once
if (y.length)
memcpy(cast(Unqual!T *)&x[length], cast(Unqual!T *)&y[0], y.length * T.sizeof);
{
// blit all elements at once
auto xptr = cast(Unqual!T *)&x[length];
immutable size = T.sizeof;

memcpy(xptr, cast(Unqual!T *)&y[0], y.length * size);

// call postblits if they exist
static if (hasPostblit)
{
auto eptr = xptr + y.length;
for (auto ptr = xptr; ptr < eptr; ptr++)
ptr.__xpostblit();
}
}
}

return x;
Expand Down

0 comments on commit f89da31

Please sign in to comment.