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

Commit f89da31

Browse files
teodutudlang-bot
authored andcommitted
core.internal.arrray.appending.d: Optimise template _d_arrayappendT
Only call `copyEmplace` when `T` has a copy ctor and no postblit. Signed-off-by: Teodor Dutu <teodor.dutu@gmail.com>
1 parent a268ab8 commit f89da31

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/core/internal/array/appending.d

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,35 @@ ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @
8585
import core.internal.traits : hasElaborateCopyConstructor, Unqual;
8686
import core.lifetime : copyEmplace;
8787

88+
enum hasPostblit = __traits(hasPostblit, T);
8889
auto length = x.length;
8990

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

92-
static if (hasElaborateCopyConstructor!T)
93+
// Only call `copyEmplace` if `T` has a copy ctor and no postblit.
94+
static if (hasElaborateCopyConstructor!T && !hasPostblit)
9395
{
9496
foreach (i, ref elem; y)
9597
copyEmplace(elem, x[length + i]);
9698
}
9799
else
98100
{
99-
// blit all elements at once
100101
if (y.length)
101-
memcpy(cast(Unqual!T *)&x[length], cast(Unqual!T *)&y[0], y.length * T.sizeof);
102+
{
103+
// blit all elements at once
104+
auto xptr = cast(Unqual!T *)&x[length];
105+
immutable size = T.sizeof;
106+
107+
memcpy(xptr, cast(Unqual!T *)&y[0], y.length * size);
108+
109+
// call postblits if they exist
110+
static if (hasPostblit)
111+
{
112+
auto eptr = xptr + y.length;
113+
for (auto ptr = xptr; ptr < eptr; ptr++)
114+
ptr.__xpostblit();
115+
}
116+
}
102117
}
103118

104119
return x;

0 commit comments

Comments
 (0)