3 import core.internal.attributes : betterC;
7 Given a pointer `chunk` to uninitialized memory (but already typed
8 as `T`), constructs an object of non-`class` type `T` at that
9 address. If `T` is a class, initializes the class reference to null.
10 Returns: A pointer to the newly constructed object (which is the same
13 T* emplace(T)(T* chunk) @safe pure nothrow
15 import core.internal.lifetime : emplaceRef;
31 assert(s2[0].i == 42 && s2[1].i == 42);
50 Given a pointer `chunk` to uninitialized memory (but already typed
51 as a non-class type `T`), constructs an object of type `T` at
52 that address from arguments `args`. If `T` is a class, initializes
53 the class reference to `args[0]`.
54 This function can be `@trusted` if the corresponding constructor of
56 Returns: A pointer to the newly constructed object (which is the same
59 T* emplace(T, Args...)(T* chunk, auto ref Args args)
60 if (is(T == struct) || Args.length == 1)
62 import core.internal.lifetime : emplaceRef;
64 emplaceRef!T(*chunk, forward!args);
74 assert(*emplace!int(&a, b) == 42);
86 Given a raw memory area `chunk` (but already typed as a class type `T`),
87 constructs an object of `class` type `T` at that address. The constructor
88 is passed the arguments `Args`.
89 If `T` is an inner class whose `outer` field can be used to access an instance
90 of the enclosing class, then `Args` must not be empty, and the first member of it
91 must be a valid initializer for that `outer` field. Correct initialization of
92 this field is essential to access members of the outer class inside `T` methods.
94 This function is `@safe` if the corresponding constructor of `T` is `@safe`.
95 Returns: The newly constructed object.
97 T emplace(T, Args...)(T chunk, auto ref Args args)
100 import core.internal.traits : isInnerClass;
102 static assert(!__traits(isAbstractClass, T), T.stringof ~
103 " is abstract and it can't be emplaced");
105 // Initialize the object in its pre-ctor state
106 const initializer = __traits(initSymbol, T);
107 (() @trusted { (cast(void*) chunk)[0 .. initializer.length] = initializer[]; })();
109 static if (isInnerClass!T)
111 static assert(Args.length > 0,
112 "Initializing an inner class requires a pointer to the outer class");
113 static assert(is(Args[0] : typeof(T.outer)),
114 "The first argument must be a pointer to the outer class");
116 chunk.outer = args[0];
117 alias args1 = args[1..$];
119 else alias args1 = args;
121 // Call the ctor if any
122 static if (is(typeof(chunk.__ctor(forward!args1))))
124 // T defines a genuine constructor accepting args
125 // Go the classic route: write .init first, then call ctor
126 chunk.__ctor(forward!args1);
130 static assert(args1.length == 0 && !is(typeof(&T.__ctor)),
131 "Don't know how to initialize an object of type "
132 ~ T.stringof ~ " with arguments " ~ typeof(args1).stringof);
144 @safe this(int x) { this.x = x; }
147 auto buf = new void[__traits(classInstanceSize, SafeClass)];
148 auto support = (() @trusted => cast(SafeClass)(buf.ptr))();
149 auto safeClass = emplace!SafeClass(support, 5);
150 assert(safeClass.x == 5);
155 @system this(int x) { this.x = x; }
158 auto buf2 = new void[__traits(classInstanceSize, UnsafeClass)];
159 auto support2 = (() @trusted => cast(UnsafeClass)(buf2.ptr))();
160 static assert(!__traits(compiles, emplace!UnsafeClass(support2, 5)));
161 static assert(!__traits(compiles, emplace!UnsafeClass(buf2, 5)));
172 @safe auto getI() { return i; }
175 auto outerBuf = new void[__traits(classInstanceSize, Outer)];
176 auto outerSupport = (() @trusted => cast(Outer)(outerBuf.ptr))();
178 auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
179 auto innerSupport = (() @trusted => cast(Outer.Inner)(innerBuf.ptr))();
181 auto inner = innerSupport.emplace!(Outer.Inner)(outerSupport.emplace!Outer);
182 assert(inner.getI == 3);
186 Given a raw memory area `chunk`, constructs an object of `class` type `T` at
187 that address. The constructor is passed the arguments `Args`.
188 If `T` is an inner class whose `outer` field can be used to access an instance
189 of the enclosing class, then `Args` must not be empty, and the first member of it
190 must be a valid initializer for that `outer` field. Correct initialization of
191 this field is essential to access members of the outer class inside `T` methods.
193 `chunk` must be at least as large as `T` needs and should have an alignment
194 multiple of `T`'s alignment. (The size of a `class` instance is obtained by using
195 $(D __traits(classInstanceSize, T))).
197 This function can be `@trusted` if the corresponding constructor of `T` is `@safe`.
198 Returns: The newly constructed object.
200 T emplace(T, Args...)(void[] chunk, auto ref Args args)
203 import core.internal.traits : maxAlignment;
205 enum classSize = __traits(classInstanceSize, T);
206 assert(chunk.length >= classSize, "chunk size too small.");
208 enum alignment = maxAlignment!(void*, typeof(T.tupleof));
209 assert((cast(size_t) chunk.ptr) % alignment == 0, "chunk is not aligned.");
211 return emplace!T(cast(T)(chunk.ptr), forward!args);
220 this(int i){this.i = i;}
222 auto buf = new void[__traits(classInstanceSize, C)];
223 auto c = emplace!C(buf, 5);
229 @nogc pure nothrow @system unittest
231 // works with -betterC too:
233 static extern (C++) class C
235 @nogc pure nothrow @safe:
242 int virtualGetI() { return i; }
245 import core.internal.traits : classInstanceAlignment;
247 align(classInstanceAlignment!C) byte[__traits(classInstanceSize, C)] buffer;
248 C c = emplace!C(buffer[], 42);
249 assert(c.virtualGetI() == 42);
259 auto getI() { return i; }
262 auto outerBuf = new void[__traits(classInstanceSize, Outer)];
263 auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
264 auto inner = innerBuf.emplace!(Outer.Inner)(outerBuf.emplace!Outer);
265 assert(inner.getI == 3);
268 @nogc pure nothrow @safe unittest
270 static class __conv_EmplaceTestClass
272 @nogc @safe pure nothrow:
284 this(int i, ref int j)
286 assert(this.i == 3 && i == 5 && j == 6);
293 align(__conv_EmplaceTestClass.alignof) ubyte[__traits(classInstanceSize, __conv_EmplaceTestClass)] buf;
294 auto support = (() @trusted => cast(__conv_EmplaceTestClass)(buf.ptr))();
296 auto fromRval = emplace!__conv_EmplaceTestClass(support, 1);
297 assert(fromRval.i == 11);
299 auto fromLval = emplace!__conv_EmplaceTestClass(support, var);
300 assert(fromLval.i == 26);
302 auto k = emplace!__conv_EmplaceTestClass(support, 5, var);
308 Given a raw memory area `chunk`, constructs an object of non-$(D
309 class) type `T` at that address. The constructor is passed the
310 arguments `args`, if any.
312 `chunk` must be at least as large
313 as `T` needs and should have an alignment multiple of `T`'s
316 This function can be `@trusted` if the corresponding constructor of
318 Returns: A pointer to the newly constructed object.
320 T* emplace(T, Args...)(void[] chunk, auto ref Args args)
323 import core.internal.traits : Unqual;
324 import core.internal.lifetime : emplaceRef;
326 assert(chunk.length >= T.sizeof, "chunk size too small.");
327 assert((cast(size_t) chunk.ptr) % T.alignof == 0, "emplace: Chunk is not aligned.");
329 emplaceRef!(T, Unqual!T)(*cast(Unqual!T*) chunk.ptr, forward!args);
330 return cast(T*) chunk.ptr;
341 void[S.sizeof] buf = void;
345 auto s1 = emplace!S(buf, s);
346 assert(s1.a == 42 && s1.b == 43);
349 // Bulk of emplace unittests starts here
352 @system unittest /* unions */
367 assert(u1.a == "hello");
370 @system unittest // bugzilla 15772
372 abstract class Foo {}
375 // test in emplaceInitializer
376 static assert(!is(typeof(emplace!Foo(cast(Foo*) memory.ptr))));
377 static assert( is(typeof(emplace!Bar(cast(Bar*) memory.ptr))));
378 // test in the emplace overload that takes void[]
379 static assert(!is(typeof(emplace!Foo(memory))));
380 static assert( is(typeof(emplace!Bar(memory))));
386 struct S { @disable this(); }
388 static assert(!__traits(compiles, emplace(&s)));
426 static assert(!__traits(compiles, emplace(&ss2)));
429 static assert(!__traits(compiles, emplace(&ss1, s1)));
445 assert(ss1[0].i == 5 && ss1[1].i == 5);
450 //Start testing emplace-args here
457 K k = null, k2 = new K;
473 void opAssign(S){assert(0);}
478 assert(sa[0].i == 5 && sa[1].i == 5);
481 //Start testing emplace-struct here
483 // Test constructor branch
492 assert(x == 5 && y == 6);
498 void[S.sizeof] s1 = void;
500 assert(*emplace!S(cast(S*) s1.ptr, s2) == s2);
501 assert(*emplace!S(cast(S*) s1, 44, 45) == S(44, 45));
506 static struct __conv_EmplaceTest
511 assert(this.i == 3 && i == 5);
514 this(int i, ref int j)
516 assert(i == 5 && j == 6);
527 __conv_EmplaceTest k = void;
532 __conv_EmplaceTest x = void;
538 auto z = emplace!__conv_EmplaceTest(new void[__conv_EmplaceTest.sizeof], 5, var);
543 // Test matching fields branch
556 struct S { int a, b; this(int){} }
558 static assert(!__traits(compiles, emplace!S(&s, 2, 3)));
564 struct S { int a, b = 7; }
565 S s1 = void, s2 = void;
568 assert(s1.a == 2 && s1.b == 7);
570 emplace!S(&s2, 2, 3);
571 assert(s2.a == 2 && s2.b == 3);
581 void opAssign(int){assert(0);}
582 void opAssign(S){assert(0);}
593 //postblit precedence
597 //Works, but breaks in "-w -O" because of @@@9332@@@.
598 //Uncomment test when 9332 is fixed.
603 this(S other){assert(false);}
604 this(int i){this.i = i;}
608 assert(is(typeof({S b = a;}))); //Postblit
609 assert(is(typeof({S b = S(a);}))); //Constructor
619 static assert(!is(immutable S2 : S2));
621 immutable is2 = (immutable S2).init;
625 //nested structs and postblit
631 this(int i){p = [i].ptr;}
641 void opAssign(const SS)
649 assert(*ssa.s.p == 5);
650 assert(ssa.s.p != ssb.s.p);
665 static assert(!__traits(compiles, emplace(&s1, s1))); // copy disabled
666 static assert(__traits(compiles, emplace(&s1, move(s1)))); // move not affected
675 //static assert(!__traits(compiles, emplace(&s2, 1)));
676 emplace(&s2, S2.init);
684 static assert(!__traits(compiles, emplace(&ss1, ss1))); // copying disabled
685 static assert(__traits(compiles, emplace(&ss1, move(ss1)))); // move unaffected
693 static assert(!__traits(compiles, emplace(&ss2, ss2))); // copying disabled
694 static assert(__traits(compiles, emplace(&ss2, SS2.init))); // move is OK
697 // SS1 sss1 = s1; //This doesn't compile
698 // SS1 sss1 = SS1(s1); //This doesn't compile
699 // So emplace shouldn't compile either
700 static assert(!__traits(compiles, emplace(&sss1, s1)));
701 static assert(!__traits(compiles, emplace(&sss2, s2)));
708 //Castable immutability
714 static assert(is( immutable(S1) : S1));
716 auto sb = immutable(S1)(5);
720 //Un-castable immutability
726 static assert(!is(immutable(S2) : S2));
728 auto sb = immutable(S2)(null);
729 assert(!__traits(compiles, emplace(&sa, sb)));
742 emplace(&s, 1, null);
743 emplace(&s, 2, &s.i);
744 assert(s is S(2, &s.i));
793 SS1 ss = SS1(1, S(2));
803 S foo() @property{return s;}
807 SS2 ss = SS2(1, S(2));
813 version (CoreUnittest)
816 private struct __std_conv_S
819 this(__std_conv_SS ss) {assert(0);}
820 static opCall(__std_conv_SS ss)
822 __std_conv_S s; s.i = ss.j;
826 private struct __std_conv_SS
830 ref __std_conv_S foo() return @property {s.i = j; return s;}
837 static assert(is(__std_conv_SS : __std_conv_S));
838 __std_conv_S s = void;
839 __std_conv_SS ss = __std_conv_SS(1);
841 __std_conv_S sTest1 = ss; //this calls "SS alias this" (and not "S.this(SS)")
842 emplace(&s, ss); //"alias this" should take precedence in emplace over "opCall"
857 assert(s1.a is s2.a);
860 //safety & nothrow & CTFE
864 //emplace should be safe for anything with no elaborate opassign
872 this(int j)@safe nothrow{i = j;}
883 void foo() @safe nothrow
889 emplace(ps1, S1.init);
892 emplace(ps2, S2.init);
898 T t/+ = void+/; //CTFE void illegal
904 static assert(a == 5);
906 static assert(b.i == 5);
908 static assert(c.i == 5);
923 int[2] get(){return [1, 2];}
939 assert(ss.ii == [1, 2]);
940 assert(iss.ii == [1, 2]);
949 @disable void opAssign(S);
960 //Without constructor
965 static S1 opCall(int*){assert(0);}
968 static assert(!__traits(compiles, emplace(&s, 1)));
975 static S2 opCall(int*){assert(0);}
976 static S2 opCall(int){assert(0);}
977 this(int i){this.i = i;}
983 //With postblit ambiguity
988 static S3 opCall(ref S3){assert(0);}
991 emplace(&s, S3.init);
1004 immutable int[2] ii;
1015 static assert(!__traits(compiles, {S ss = S(uu);}));
1016 static assert(!__traits(compiles, emplace(&s, uu)));
1029 emplace(&sii, sii2);
1030 //emplace(&sii, uii2); //Sorry, this implementation doesn't know how to...
1031 //emplace(&uii, sii2); //Sorry, this implementation doesn't know how to...
1032 emplace(&uii, uii2);
1033 emplace(&sii, sii2[]);
1034 //emplace(&sii, uii2[]); //Sorry, this implementation doesn't know how to...
1035 //emplace(&uii, sii2[]); //Sorry, this implementation doesn't know how to...
1036 emplace(&uii, uii2[]);
1041 bool allowDestruction = false;
1046 ~this(){assert(allowDestruction);}
1054 emplace(&ss3, ss2[]);
1055 assert(ss1[1] == s);
1056 assert(ss2[1] == s);
1057 assert(ss3[1] == s);
1058 allowDestruction = true;
1063 //Checks postblit, construction, and context pointer
1093 S[2][2][2] sss = void;
1097 @system unittest //Constness
1099 import core.internal.lifetime : emplaceRef;
1102 emplaceRef!(const int)(a, 5);
1105 const(int)* p = void;
1106 emplaceRef!(const int*)(p, &i);
1112 alias IS = immutable(S);
1114 emplaceRef!IS(s, IS());
1116 emplaceRef!(IS[2])(ss, IS());
1118 IS[2] iss = IS.init;
1119 emplaceRef!(IS[2])(ss, iss);
1120 emplaceRef!(IS[2])(ss, iss[]);
1124 pure nothrow @safe @nogc unittest
1126 import core.internal.lifetime : emplaceRef;
1132 emplaceRef!int(i, 5);
1135 // Test attribute propagation for UDTs
1136 pure nothrow @safe /* @nogc */ unittest
1138 import core.internal.lifetime : emplaceRef;
1142 this(this) pure nothrow @safe @nogc {}
1146 emplaceRef(safe, Safe());
1148 Safe[1] safeArr = [Safe()];
1149 Safe[1] uninitializedSafeArr = void;
1150 emplaceRef(uninitializedSafeArr, safe);
1151 emplaceRef(uninitializedSafeArr, safeArr);
1153 static struct Unsafe
1155 this(this) @system {}
1158 Unsafe unsafe = void;
1159 static assert(!__traits(compiles, emplaceRef(unsafe, unsafe)));
1161 Unsafe[1] unsafeArr = [Unsafe()];
1162 Unsafe[1] uninitializedUnsafeArr = void;
1163 static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafe)));
1164 static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafeArr)));
1178 import core.stdc.stdlib : malloc;
1179 void[] buf = malloc(Node.sizeof)[0 .. Node.sizeof];
1181 const Node* n = emplace!(const Node)(buf, 42, null, 10);
1182 assert(n.payload == 42);
1183 assert(n.next == null);
1184 assert(n.refs == 10);
1195 assert(x == 5 && y == 42);
1201 static align(A.alignof) byte[__traits(classInstanceSize, A)] sbuf;
1203 auto a = emplace!A(buf, 55);
1204 assert(a.x == 55 && a.y == 55);
1206 // emplace in bigger buffer
1207 buf = new byte[](__traits(classInstanceSize, A) + 10);
1208 a = emplace!A(buf, 55);
1209 assert(a.x == 55 && a.y == 55);
1212 static assert(!is(typeof(emplace!A(buf))));
1215 //constructor arguments forwarding
1221 this()(auto ref long arg)
1223 // assert that arg is an lvalue
1224 static assert(__traits(isRef, arg));
1226 this()(auto ref double arg)
1227 // assert that arg is an rvalue
1229 static assert(!__traits(isRef, arg));
1234 emplace(&obj, i); // lvalue
1235 emplace(&obj, 0.0); // rvalue
1237 // Bulk of emplace unittests ends here
1240 * Emplaces a copy of the specified source value into uninitialized memory,
1241 * i.e., simulates `T target = source` copy-construction for cases where the
1242 * target memory is already allocated and to be initialized with a copy.
1245 * source = value to be copied into target
1246 * target = uninitialized value to be initialized with a copy of source
1248 void copyEmplace(S, T)(ref S source, ref T target) @system
1249 if (is(immutable S == immutable T))
1251 import core.internal.traits : BaseElemOf, hasElaborateCopyConstructor, Unconst, Unqual;
1253 // cannot have the following as simple template constraint due to nested-struct special case...
1254 static if (!__traits(compiles, (ref S src) { T tgt = src; }))
1256 alias B = BaseElemOf!T;
1257 enum isNestedStruct = is(B == struct) && __traits(isNested, B);
1258 static assert(isNestedStruct, "cannot copy-construct " ~ T.stringof ~ " from " ~ S.stringof);
1263 import core.stdc.string : memcpy;
1264 memcpy(cast(Unqual!(T)*) &target, cast(Unqual!(T)*) &source, T.sizeof);
1267 static if (is(T == struct))
1269 static if (__traits(hasPostblit, T))
1272 (cast() target).__xpostblit();
1274 else static if (__traits(hasCopyConstructor, T))
1276 emplace(cast(Unqual!(T)*) &target); // blit T.init
1277 static if (__traits(isNested, T))
1279 // copy context pointer
1280 *(cast(void**) &target.tupleof[$-1]) = cast(void*) source.tupleof[$-1];
1282 target.__ctor(source); // invoke copy ctor
1286 blit(); // no opAssign
1289 else static if (is(T == E[n], E, size_t n))
1291 static if (hasElaborateCopyConstructor!E)
1296 for (i = 0; i < n; i++)
1297 copyEmplace(source[i], target[i]);
1301 // destroy, in reverse order, what we've constructed so far
1303 destroy(*cast(Unconst!(E)*) &target[i]);
1307 else // trivial copy
1309 blit(); // all elements at once
1314 *cast(Unconst!(T)*) &target = *cast(Unconst!(T)*) &source;
1320 @system pure nothrow @nogc unittest
1324 copyEmplace(source, target);
1325 assert(target == 123);
1330 @system pure nothrow @nogc unittest
1332 immutable int[1][1] source = [ [123] ];
1333 immutable int[1][1] target = void;
1334 copyEmplace(source, target);
1335 assert(target[0][0] == 123);
1340 @system pure nothrow @nogc unittest
1345 void opAssign(const scope ref S rhs) @safe pure nothrow @nogc
1353 copyEmplace(source, target);
1354 assert(target.x == 42);
1357 // preserve shared-ness
1358 @system pure nothrow unittest
1360 auto s = new Object();
1361 auto ss = new shared Object();
1369 copyEmplace(ss, st);
1372 static assert(!__traits(compiles, copyEmplace(s, st)));
1373 static assert(!__traits(compiles, copyEmplace(ss, t)));
1376 version (DigitalMars) version (X86) version (Posix) version = DMD_X86_Posix;
1378 // don't violate immutability for reference types
1379 @system pure nothrow unittest
1381 auto s = new Object();
1382 auto si = new immutable Object();
1385 immutable Object ti;
1390 copyEmplace(si, ti);
1391 version (DMD_X86_Posix) { /* wrongly fails without -O */ } else
1394 static assert(!__traits(compiles, copyEmplace(s, ti)));
1395 static assert(!__traits(compiles, copyEmplace(si, t)));
1398 version (CoreUnittest)
1400 private void testCopyEmplace(S, T)(const scope T* expected = null)
1404 copyEmplace(source, target);
1406 assert(target == *expected);
1409 T expectedCopy = source;
1410 assert(target == expectedCopy);
1416 @system pure nothrow @nogc unittest
1420 @safe pure nothrow @nogc:
1422 this(this) { x += 10; }
1425 testCopyEmplace!(S, S)();
1426 testCopyEmplace!(immutable S, S)();
1427 testCopyEmplace!(S, immutable S)();
1428 testCopyEmplace!(immutable S, immutable S)();
1430 testCopyEmplace!(S[1], S[1])();
1431 testCopyEmplace!(immutable S[1], S[1])();
1433 // copying to an immutable static array works, but `T expected = source`
1434 // wrongly ignores the postblit: https://issues.dlang.org/show_bug.cgi?id=8950
1435 immutable S[1] expectedImmutable = [S(52)];
1436 testCopyEmplace!(S[1], immutable S[1])(&expectedImmutable);
1437 testCopyEmplace!(immutable S[1], immutable S[1])(&expectedImmutable);
1440 // copy constructors
1441 @system pure nothrow @nogc unittest
1445 @safe pure nothrow @nogc:
1447 this(int x) { this.x = x; }
1448 this(const scope ref S rhs) { x = rhs.x + 10; }
1449 this(const scope ref S rhs) immutable { x = rhs.x + 20; }
1452 testCopyEmplace!(S, S)();
1453 testCopyEmplace!(immutable S, S)();
1454 testCopyEmplace!(S, immutable S)();
1455 testCopyEmplace!(immutable S, immutable S)();
1457 // static arrays work, but `T expected = source` wrongly ignores copy ctors
1458 // https://issues.dlang.org/show_bug.cgi?id=20365
1459 S[1] expectedMutable = [S(52)];
1460 immutable S[1] expectedImmutable = [immutable S(62)];
1461 testCopyEmplace!(S[1], S[1])(&expectedMutable);
1462 testCopyEmplace!(immutable S[1], S[1])(&expectedMutable);
1463 testCopyEmplace!(S[1], immutable S[1])(&expectedImmutable);
1464 testCopyEmplace!(immutable S[1], immutable S[1])(&expectedImmutable);
1467 // copy constructor in nested struct
1468 @system pure nothrow unittest
1473 @safe pure nothrow @nogc:
1475 this(size_t x) { this.x = x; }
1476 this(const scope ref S rhs)
1478 assert(x == 42); // T.init
1487 immutable S target = void;
1488 copyEmplace(source, target);
1489 assert(target is source);
1490 assert(copies == 1);
1495 immutable S[1] source = [immutable S(456)];
1497 copyEmplace(source, target);
1498 assert(target[0] is source[0]);
1499 assert(copies == 1);
1503 // destruction of partially copied static array
1508 __gshared int[] deletions;
1510 this(this) { if (x == 5) throw new Exception(""); }
1511 ~this() { deletions ~= x; }
1514 alias T = immutable S[3][2];
1515 T source = [ [S(1), S(2), S(3)], [S(4), S(5), S(6)] ];
1519 copyEmplace(source, target);
1524 static immutable expectedDeletions = [ 4, 3, 2, 1 ];
1525 version (DigitalMars)
1527 assert(S.deletions == expectedDeletions ||
1528 S.deletions == [ 4 ]); // FIXME: happens with -O
1531 assert(S.deletions == expectedDeletions);
1536 Forwards function arguments while keeping `out`, `ref`, and `lazy` on
1540 args = a parameter list or an $(REF AliasSeq,std,meta).
1542 An `AliasSeq` of `args` with `out`, `ref`, and `lazy` saved.
1544 template forward(args...)
1546 import core.internal.traits : AliasSeq;
1548 static if (args.length)
1550 alias arg = args[0];
1551 // by ref || lazy || const/immutable
1552 static if (__traits(isRef, arg) ||
1553 __traits(isOut, arg) ||
1554 __traits(isLazy, arg) ||
1555 !is(typeof(move(arg))))
1559 @property auto fwd(){ return move(arg); }
1561 static if (args.length == 1)
1562 alias forward = fwd;
1564 alias forward = AliasSeq!(fwd, forward!(args[1..$]));
1567 alias forward = AliasSeq!();
1575 static int foo(int n) { return 1; }
1576 static int foo(ref int n) { return 2; }
1580 int bar()(auto ref int x) { return C.foo(forward!x); }
1583 int baz()(auto ref int x) { return C.foo(x); }
1586 assert(bar(1) == 1);
1587 assert(bar(i) == 2);
1589 assert(baz(1) == 2);
1590 assert(baz(i) == 2);
1596 void foo(int n, ref string s) { s = null; foreach (i; 0 .. n) s ~= "Hello"; }
1598 // forwards all arguments which are bound to parameter tuple
1599 void bar(Args...)(auto ref Args args) { return foo(forward!args); }
1601 // forwards all arguments with swapping order
1602 void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }
1606 assert(s == "Hello");
1608 assert(s == "HelloHello");
1613 auto foo(TL...)(auto ref TL args)
1616 foreach (i, _; args)
1618 //pragma(msg, "[",i,"] ", __traits(isRef, args[i]) ? "L" : "R");
1619 result ~= __traits(isRef, args[i]) ? "L" : "R";
1624 string bar(TL...)(auto ref TL args)
1626 return foo(forward!args);
1628 string baz(TL...)(auto ref TL args)
1631 return foo(forward!args[3], forward!args[2], 1, forward!args[1], forward!args[0], x);
1635 S makeS(){ return S(); }
1638 assert(bar(S(), makeS(), n, s) == "RRLL");
1639 assert(baz(S(), makeS(), n, s) == "LLRRRL");
1645 ref int foo(return ref int a) { return a; }
1646 ref int bar(Args)(auto ref Args args)
1648 return foo(forward!args);
1650 static assert(!__traits(compiles, { auto x1 = bar(3); })); // case of NG
1652 auto x2 = bar(value); // case of OK
1670 this()(auto ref X x)
1679 this()(auto ref X x)
1683 this()(auto const ref X x)
1691 auto constX = (){ const X x; return x; };
1692 static assert(__traits(compiles, { Y y = x; }));
1693 static assert(__traits(compiles, { Y y = X(); }));
1694 static assert(!__traits(compiles, { Y y = cx; }));
1695 static assert(!__traits(compiles, { Y y = constX(); }));
1696 static assert(__traits(compiles, { Z z = x; }));
1697 static assert(__traits(compiles, { Z z = X(); }));
1698 static assert(__traits(compiles, { Z z = cx; }));
1699 static assert(__traits(compiles, { Z z = constX(); }));
1704 assert(y1.x_.i == 1);
1707 assert(y2.x_.i == 0);
1711 assert(z1.x_.i == 1);
1714 assert(z2.x_.i == 0);
1716 // ref const lvalue, copy
1717 assert(z3.x_.i == 1);
1719 // const rvalue, copy
1720 assert(z4.x_.i == 1);
1727 int foo1(lazy int i) { return i; }
1728 int foo2(A)(auto ref A i) { return foo1(forward!i); }
1729 int foo3(lazy int i) { return foo2(i); }
1732 assert(foo3({ ++numCalls; return 42; }()) == 42);
1733 assert(numCalls == 1);
1740 int foo1(int a, int b) { return a + b; }
1741 int foo2(A...)(auto ref A args) { return foo1(forward!args); }
1742 int foo3(int a, lazy int b) { return foo2(a, b); }
1745 assert(foo3(11, { ++numCalls; return 31; }()) == 42);
1746 assert(numCalls == 1);
1753 int foo1(int a, lazy int b) { return a + b; }
1754 int foo2(A...)(auto ref A args) { return foo1(forward!args); }
1755 int foo3(int a, int b) { return foo2(a, b); }
1757 assert(foo3(11, 31) == 42);
1764 void foo1(int a, out int b) { b = a; }
1765 void foo2(A...)(auto ref A args) { foo1(forward!args); }
1766 void foo3(int a, out int b) { foo2(a, b); }
1775 Moves `source` into `target`, via a destructive copy when necessary.
1777 If `T` is a struct with a destructor or postblit defined, source is reset
1778 to its `.init` value after it is moved into target, otherwise it is
1782 If source has internal pointers that point to itself and doesn't define
1783 opPostMove, it cannot be moved, and will trigger an assertion failure.
1786 source = Data to copy.
1787 target = Where to copy into. The destructor, if any, is invoked before the
1790 void move(T)(ref T source, ref T target)
1792 moveImpl(target, source);
1795 /// For non-struct types, `move` just performs `target = source`:
1798 Object obj1 = new Object;
1803 assert(obj3 is obj1);
1805 assert(obj2 is obj1);
1809 pure nothrow @safe @nogc unittest
1811 // Structs without destructors are simply copied
1817 S1 s11 = { 10, 11 };
1822 assert(s12 == S1(10, 11));
1825 // But structs with destructors or postblits are reset to their .init value
1826 // after copying to the target.
1832 ~this() pure nothrow @safe @nogc { }
1839 assert(s21 == S2(1, 2));
1840 assert(s22 == S2(3, 4));
1845 import core.internal.traits;
1848 Object obj1 = new Object;
1852 assert(obj3 is obj1);
1854 static struct S1 { int a = 1, b = 2; }
1855 S1 s11 = { 10, 11 };
1858 assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
1860 static struct S2 { int a = 1; int * b; }
1861 S2 s21 = { 10, null };
1867 // Issue 5661 test(1)
1870 static struct X { int n = 0; ~this(){n = 0;} }
1873 static assert(hasElaborateDestructor!S3);
1877 assert(s31.x.n == 0);
1878 assert(s32.x.n == 1);
1880 // Issue 5661 test(2)
1883 static struct X { int n = 0; this(this){n = 0;} }
1886 static assert(hasElaborateCopyConstructor!S4);
1890 assert(s41.x.n == 0);
1891 assert(s42.x.n == 1);
1904 T move(T)(return scope ref T source)
1906 return moveImpl(source);
1909 /// Non-copyable structs can still be moved:
1910 pure nothrow @safe @nogc unittest
1915 @disable this(this);
1916 ~this() pure nothrow @safe @nogc {}
1925 // https://issues.dlang.org/show_bug.cgi?id=20869
1926 // `move` should propagate the attributes of `opPostMove`
1931 void opPostMove(const ref S old) nothrow @system
1934 new int(i++); // Force @gc impure @system
1938 alias T = void function() @system nothrow;
1939 static assert(is(typeof({ S s; move(s); }) == T));
1940 static assert(is(typeof({ S s; move(s, s); }) == T));
1943 private void moveImpl(T)(scope ref T target, return scope ref T source)
1945 import core.internal.traits : hasElaborateDestructor;
1947 static if (is(T == struct))
1949 // Unsafe when compiling without -preview=dip1000
1950 if ((() @trusted => &source == &target)()) return;
1951 // Destroy target before overwriting it
1952 static if (hasElaborateDestructor!T) target.__xdtor();
1954 // move and emplace source into target
1955 moveEmplaceImpl(target, source);
1958 private T moveImpl(T)(return scope ref T source)
1960 // Properly infer safety from moveEmplaceImpl as the implementation below
1961 // might void-initialize pointers in result and hence needs to be @trusted
1962 if (false) moveEmplaceImpl(source, source);
1964 return trustedMoveImpl(source);
1967 private T trustedMoveImpl(T)(return scope ref T source) @trusted
1970 moveEmplaceImpl(result, source);
1976 import core.internal.traits;
1979 Object obj1 = new Object;
1981 Object obj3 = move(obj2);
1982 assert(obj3 is obj1);
1984 static struct S1 { int a = 1, b = 2; }
1985 S1 s11 = { 10, 11 };
1987 assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
1989 static struct S2 { int a = 1; int * b; }
1990 S2 s21 = { 10, null };
1996 // Issue 5661 test(1)
1999 static struct X { int n = 0; ~this(){n = 0;} }
2002 static assert(hasElaborateDestructor!S3);
2006 assert(s31.x.n == 0);
2007 assert(s32.x.n == 1);
2009 // Issue 5661 test(2)
2012 static struct X { int n = 0; this(this){n = 0;} }
2015 static assert(hasElaborateCopyConstructor!S4);
2019 assert(s41.x.n == 0);
2020 assert(s42.x.n == 1);
2035 static struct S { int n = 0; ~this() @system { n = 0; } }
2037 static assert(!__traits(compiles, () @safe { move(a, b); }));
2038 static assert(!__traits(compiles, () @safe { move(a); }));
2040 () @trusted { move(a, b); }();
2043 () @trusted { move(a); }();
2046 /+ this can't be tested in druntime, tests are still run in phobos
2047 @safe unittest//Issue 6217
2049 import std.algorithm.iteration : map;
2050 auto x = map!"a"([1,2,3]);
2055 @safe unittest// Issue 8055
2075 @system unittest// Issue 8057
2083 // Access to enclosing scope
2089 // Move nested struct
2098 static struct Array(T)
2100 // nested struct has no member
2106 Array!int.Payload x = void;
2111 // target must be first-parameter, because in void-functions DMD + dip1000 allows it to take the place of a return-scope
2112 private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
2114 import core.stdc.string : memcpy, memset;
2115 import core.internal.traits;
2117 // TODO: this assert pulls in half of phobos. we need to work out an alternative assert strategy.
2118 // static if (!is(T == class) && hasAliasing!T) if (!__ctfe)
2120 // import std.exception : doesPointTo;
2121 // assert(!doesPointTo(source, source) && !hasElaborateMove!T),
2122 // "Cannot move object with internal pointer unless `opPostMove` is defined.");
2125 static if (is(T == struct))
2127 // Unsafe when compiling without -preview=dip1000
2128 assert((() @trusted => &source !is &target)(), "source and target must not be identical");
2130 static if (hasElaborateAssign!T || !isAssignable!T)
2131 () @trusted { memcpy(&target, &source, T.sizeof); }();
2135 static if (hasElaborateMove!T)
2136 __move_post_blt(target, source);
2138 // If the source defines a destructor or a postblit hook, we must obliterate the
2139 // object in order to avoid double freeing and undue aliasing
2140 static if (hasElaborateDestructor!T || hasElaborateCopyConstructor!T)
2142 // If T is nested struct, keep original context pointer
2143 static if (__traits(isNested, T))
2144 enum sz = T.sizeof - (void*).sizeof;
2148 static if (__traits(isZeroInit, T))
2149 () @trusted { memset(&source, 0, sz); }();
2151 () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }();
2154 else static if (__traits(isStaticArray, T))
2156 for (size_t i = 0; i < source.length; ++i)
2157 move(source[i], target[i]);
2161 // Primitive data (including pointers and arrays) or class -
2162 // assignment works great
2168 * Similar to $(LREF move) but assumes `target` is uninitialized. This
2169 * is more efficient because `source` can be blitted over `target`
2170 * without destroying or initializing it first.
2173 * source = value to be moved into target
2174 * target = uninitialized value to be filled by source
2176 void moveEmplace(T)(ref T source, ref T target) @system
2178 moveEmplaceImpl(target, source);
2183 pure nothrow @nogc @system unittest
2188 this(int* ptr) { _ptr = ptr; }
2189 ~this() { if (_ptr) ++*_ptr; }
2194 Foo foo1 = void; // uninitialized
2195 auto foo2 = Foo(&val); // initialized
2196 assert(foo2._ptr is &val);
2198 // Using `move(foo2, foo1)` would have an undefined effect because it would destroy
2199 // the uninitialized foo1.
2200 // moveEmplace directly overwrites foo1 without destroying or initializing it first.
2201 moveEmplace(foo2, foo1);
2202 assert(foo1._ptr is &val);
2203 assert(foo2._ptr is null);
2210 static struct NoCopy
2214 @disable this(this);
2217 static void f(NoCopy[2]) { }
2219 NoCopy[2] ncarray = [ NoCopy(1), NoCopy(2) ];
2221 static assert(!__traits(compiles, f(ncarray)));
2226 * This is called for a delete statement where the value
2227 * being deleted is a pointer to a struct with a destructor
2228 * but doesn't have an overloaded delete operator.
2231 * p = pointer to the value to be deleted
2233 void _d_delstruct(T)(ref T *p)
2237 debug(PRINTF) printf("_d_delstruct(%p)\n", p);
2239 import core.memory : GC;
2250 struct S { ~this() { ++dtors; } }
2264 struct Inner { ~this() { ++innerDtors; } }
2288 Outer *o = new Outer(0);
2292 assert(innerDtors == 2);
2293 assert(outerDtors == 1);