1 module nxt.emplace_all;
2 
3 /** Version of `std.algorithm.mutation.moveEmplaceAll` that works for uncopyable
4  * element type `T`.
5  */
6 void moveEmplaceAllNoReset(T)(scope T[] src,
7                               scope T[] tgt)
8 {
9     assert(src.length == tgt.length);
10     import nxt.container_traits : needsMove;
11     static if (needsMove!T)
12     {
13         immutable n = src.length;
14         // TODO benchmark with `memmove` and `memset` instead
15         foreach (i; 0 .. n)
16         {
17             import core.lifetime : moveEmplace;
18             moveEmplace(src[i], tgt[i]);
19         }
20     }
21     else
22     {
23         tgt[] = src[];
24         src[] = T.init;
25     }
26 }
27 
28 @trusted pure nothrow @nogc unittest
29 {
30     import nxt.uncopyable_sample : SomeUncopyable;
31 
32     alias T = SomeUncopyable;
33     enum n = 3;
34     alias A = T[n];
35 
36     A x = [T(1), T(2), T(3)];
37     A y = void;
38     moveEmplaceAllNoReset(x[], y[]);
39 
40     foreach (immutable i; 0 .. n)
41     {
42         assert(x[i] == T.init);
43         assert(*y[i].valuePointer == i + 1);
44     }
45 }