The OpenD Programming Language

1 module core.lifetime;
2 
3 import core.internal.attributes : betterC;
4 
5 // emplace
6 /**
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
11 as `chunk`).
12  */
13 T* emplace(T)(T* chunk) @safe pure nothrow
14 {
15     import core.internal.lifetime : emplaceRef;
16 
17     emplaceRef!T(*chunk);
18     return chunk;
19 }
20 
21 ///
22 @betterC
23 @system unittest
24 {
25     static struct S
26     {
27         int i = 42;
28     }
29     S[2] s2 = void;
30     emplace(&s2);
31     assert(s2[0].i == 42 && s2[1].i == 42);
32 }
33 
34 ///
35 @system unittest
36 {
37     interface I {}
38     class K : I {}
39 
40     K k = void;
41     emplace(&k);
42     assert(k is null);
43 
44     I i = void;
45     emplace(&i);
46     assert(i is null);
47 }
48 
49 /**
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
55 `T` is `@safe`.
56 Returns: A pointer to the newly constructed object (which is the same
57 as `chunk`).
58  */
59 T* emplace(T, Args...)(T* chunk, auto ref Args args)
60     if (is(T == struct) || Args.length == 1)
61 {
62     import core.internal.lifetime : emplaceRef;
63 
64     emplaceRef!T(*chunk, forward!args);
65     return chunk;
66 }
67 
68 ///
69 @betterC
70 @system unittest
71 {
72     int a;
73     int b = 42;
74     assert(*emplace!int(&a, b) == 42);
75 }
76 
77 @betterC
78 @system unittest
79 {
80     shared int i;
81     emplace(&i, 42);
82     assert(i == 42);
83 }
84 
85 /**
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.
93 Note:
94 This function is `@safe` if the corresponding constructor of `T` is `@safe`.
95 Returns: The newly constructed object.
96  */
97 T emplace(T, Args...)(T chunk, auto ref Args args)
98     if (is(T == class))
99 {
100     import core.internal.traits : isInnerClass;
101 
102     static assert(!__traits(isAbstractClass, T), T.stringof ~
103         " is abstract and it can't be emplaced");
104 
105     // Initialize the object in its pre-ctor state
106     const initializer = __traits(initSymbol, T);
107     (() @trusted { (cast(void*) chunk)[0 .. initializer.length] = initializer[]; })();
108 
109     static if (isInnerClass!T)
110     {
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");
115 
116         chunk.outer = args[0];
117         alias args1 = args[1..$];
118     }
119     else alias args1 = args;
120 
121     // Call the ctor if any
122     static if (is(typeof(chunk.__ctor(forward!args1))))
123     {
124         // T defines a genuine constructor accepting args
125         // Go the classic route: write .init first, then call ctor
126         chunk.__ctor(forward!args1);
127     }
128     else
129     {
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);
133     }
134     return chunk;
135 }
136 
137 ///
138 @safe unittest
139 {
140     () @safe {
141         class SafeClass
142         {
143             int x;
144             @safe this(int x) { this.x = x; }
145         }
146 
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);
151 
152         class UnsafeClass
153         {
154             int x;
155             @system this(int x) { this.x = x; }
156         }
157 
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)));
162     }();
163 }
164 
165 @safe unittest
166 {
167     class Outer
168     {
169         int i = 3;
170         class Inner
171         {
172             @safe auto getI() { return i; }
173         }
174     }
175     auto outerBuf = new void[__traits(classInstanceSize, Outer)];
176     auto outerSupport = (() @trusted => cast(Outer)(outerBuf.ptr))();
177 
178     auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
179     auto innerSupport = (() @trusted => cast(Outer.Inner)(innerBuf.ptr))();
180 
181     auto inner = innerSupport.emplace!(Outer.Inner)(outerSupport.emplace!Outer);
182     assert(inner.getI == 3);
183 }
184 
185 /**
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.
192 Preconditions:
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))).
196 Note:
197 This function can be `@trusted` if the corresponding constructor of `T` is `@safe`.
198 Returns: The newly constructed object.
199  */
200 T emplace(T, Args...)(void[] chunk, auto ref Args args)
201     if (is(T == class))
202 {
203     enum classSize = __traits(classInstanceSize, T);
204     assert(chunk.length >= classSize, "chunk size too small.");
205 
206     enum alignment = __traits(classInstanceAlignment, T);
207     assert((cast(size_t) chunk.ptr) % alignment == 0, "chunk is not aligned.");
208 
209     return emplace!T(cast(T)(chunk.ptr), forward!args);
210 }
211 
212 ///
213 @system unittest
214 {
215     static class C
216     {
217         int i;
218         this(int i){this.i = i;}
219     }
220     auto buf = new void[__traits(classInstanceSize, C)];
221     auto c = emplace!C(buf, 5);
222     assert(c.i == 5);
223 }
224 
225 ///
226 @betterC
227 @nogc pure nothrow @system unittest
228 {
229     // works with -betterC too:
230 
231     static extern (C++) class C
232     {
233         @nogc pure nothrow @safe:
234         int i = 3;
235         this(int i)
236         {
237             assert(this.i == 3);
238             this.i = i;
239         }
240         int virtualGetI() { return i; }
241     }
242 
243     align(__traits(classInstanceAlignment, C)) byte[__traits(classInstanceSize, C)] buffer;
244     C c = emplace!C(buffer[], 42);
245     assert(c.virtualGetI() == 42);
246 }
247 
248 @system unittest
249 {
250     class Outer
251     {
252         int i = 3;
253         class Inner
254         {
255             auto getI() { return i; }
256         }
257     }
258     auto outerBuf = new void[__traits(classInstanceSize, Outer)];
259     auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
260     auto inner = innerBuf.emplace!(Outer.Inner)(outerBuf.emplace!Outer);
261     assert(inner.getI == 3);
262 }
263 
264 @nogc pure nothrow @safe unittest
265 {
266     static class __conv_EmplaceTestClass
267     {
268         @nogc @safe pure nothrow:
269         int i = 3;
270         this(int i)
271         {
272             assert(this.i == 3);
273             this.i = 10 + i;
274         }
275         this(ref int i)
276         {
277             assert(this.i == 3);
278             this.i = 20 + i;
279         }
280         this(int i, ref int j)
281         {
282             assert(this.i == 3 && i == 5 && j == 6);
283             this.i = i;
284             ++j;
285         }
286     }
287 
288     int var = 6;
289     align(__traits(classInstanceAlignment, __conv_EmplaceTestClass))
290         ubyte[__traits(classInstanceSize, __conv_EmplaceTestClass)] buf;
291     auto support = (() @trusted => cast(__conv_EmplaceTestClass)(buf.ptr))();
292 
293     auto fromRval = emplace!__conv_EmplaceTestClass(support, 1);
294     assert(fromRval.i == 11);
295 
296     auto fromLval = emplace!__conv_EmplaceTestClass(support, var);
297     assert(fromLval.i == 26);
298 
299     auto k = emplace!__conv_EmplaceTestClass(support, 5, var);
300     assert(k.i == 5);
301     assert(var == 7);
302 }
303 
304 /**
305 Given a raw memory area `chunk`, constructs an object of non-$(D
306 class) type `T` at that address. The constructor is passed the
307 arguments `args`, if any.
308 Preconditions:
309 `chunk` must be at least as large
310 as `T` needs and should have an alignment multiple of `T`'s
311 alignment.
312 Note:
313 This function can be `@trusted` if the corresponding constructor of
314 `T` is `@safe`.
315 Returns: A pointer to the newly constructed object.
316  */
317 T* emplace(T, Args...)(void[] chunk, auto ref Args args)
318     if (!is(T == class))
319 {
320     import core.internal.traits : Unqual;
321     import core.internal.lifetime : emplaceRef;
322 
323     assert(chunk.length >= T.sizeof, "chunk size too small.");
324     assert((cast(size_t) chunk.ptr) % T.alignof == 0, "emplace: Chunk is not aligned.");
325 
326     emplaceRef!(T, Unqual!T)(*cast(Unqual!T*) chunk.ptr, forward!args);
327     return cast(T*) chunk.ptr;
328 }
329 
330 ///
331 @betterC
332 @system unittest
333 {
334     struct S
335     {
336         int a, b;
337     }
338     void[S.sizeof] buf = void;
339     S s;
340     s.a = 42;
341     s.b = 43;
342     auto s1 = emplace!S(buf, s);
343     assert(s1.a == 42 && s1.b == 43);
344 }
345 
346 // Bulk of emplace unittests starts here
347 
348 @betterC
349 @system unittest /* unions */
350 {
351     static union U
352     {
353         string a;
354         int b;
355         struct
356         {
357             long c;
358             int[] d;
359         }
360     }
361     U u1 = void;
362     U u2 = { "hello" };
363     emplace(&u1, u2);
364     assert(u1.a == "hello");
365 }
366 
367 @system unittest // https://issues.dlang.org/show_bug.cgi?id=15772
368 {
369     abstract class Foo {}
370     class Bar: Foo {}
371     void[] memory;
372     // test in emplaceInitializer
373     static assert(!is(typeof(emplace!Foo(cast(Foo*) memory.ptr))));
374     static assert( is(typeof(emplace!Bar(cast(Bar*) memory.ptr))));
375     // test in the emplace overload that takes void[]
376     static assert(!is(typeof(emplace!Foo(memory))));
377     static assert( is(typeof(emplace!Bar(memory))));
378 }
379 
380 @betterC
381 @system unittest
382 {
383     struct S { @disable this(); }
384     S s = void;
385     static assert(!__traits(compiles, emplace(&s)));
386     emplace(&s, S.init);
387 }
388 
389 @betterC
390 @system unittest
391 {
392     struct S1
393     {}
394 
395     struct S2
396     {
397         void opAssign(S2);
398     }
399 
400     S1 s1 = void;
401     S2 s2 = void;
402     S1[2] as1 = void;
403     S2[2] as2 = void;
404     emplace(&s1);
405     emplace(&s2);
406     emplace(&as1);
407     emplace(&as2);
408 }
409 
410 @system unittest
411 {
412     static struct S1
413     {
414         this(this) @disable;
415     }
416     static struct S2
417     {
418         this() @disable;
419     }
420     S1[2] ss1 = void;
421     S2[2] ss2 = void;
422     emplace(&ss1);
423     static assert(!__traits(compiles, emplace(&ss2)));
424     S1 s1 = S1.init;
425     S2 s2 = S2.init;
426     static assert(!__traits(compiles, emplace(&ss1, s1)));
427     emplace(&ss2, s2);
428 }
429 
430 @system unittest
431 {
432     struct S
433     {
434         immutable int i;
435     }
436     S s = void;
437     S[2] ss1 = void;
438     S[2] ss2 = void;
439     emplace(&s, 5);
440     assert(s.i == 5);
441     emplace(&ss1, s);
442     assert(ss1[0].i == 5 && ss1[1].i == 5);
443     emplace(&ss2, ss1);
444     assert(ss2 == ss1);
445 }
446 
447 //Start testing emplace-args here
448 
449 @system unittest
450 {
451     interface I {}
452     class K : I {}
453 
454     K k = null, k2 = new K;
455     assert(k !is k2);
456     emplace!K(&k, k2);
457     assert(k is k2);
458 
459     I i = null;
460     assert(i !is k);
461     emplace!I(&i, k);
462     assert(i is k);
463 }
464 
465 @system unittest
466 {
467     static struct S
468     {
469         int i = 5;
470         void opAssign(S){assert(0);}
471     }
472     S[2] sa = void;
473     S[2] sb;
474     emplace(&sa, sb);
475     assert(sa[0].i == 5 && sa[1].i == 5);
476 }
477 
478 //Start testing emplace-struct here
479 
480 // Test constructor branch
481 @betterC
482 @system unittest
483 {
484     struct S
485     {
486         double x = 5, y = 6;
487         this(int a, int b)
488         {
489             assert(x == 5 && y == 6);
490             x = a;
491             y = b;
492         }
493     }
494 
495     void[S.sizeof] s1 = void;
496     auto s2 = S(42, 43);
497     assert(*emplace!S(cast(S*) s1.ptr, s2) == s2);
498     assert(*emplace!S(cast(S*) s1, 44, 45) == S(44, 45));
499 }
500 
501 @system unittest
502 {
503     static struct __conv_EmplaceTest
504     {
505         int i = 3;
506         this(int i)
507         {
508             assert(this.i == 3 && i == 5);
509             this.i = i;
510         }
511         this(int i, ref int j)
512         {
513             assert(i == 5 && j == 6);
514             this.i = i;
515             ++j;
516         }
517 
518     @disable:
519         this();
520         this(this);
521         void opAssign();
522     }
523 
524     __conv_EmplaceTest k = void;
525     emplace(&k, 5);
526     assert(k.i == 5);
527 
528     int var = 6;
529     __conv_EmplaceTest x = void;
530     emplace(&x, 5, var);
531     assert(x.i == 5);
532     assert(var == 7);
533 
534     var = 6;
535     auto z = emplace!__conv_EmplaceTest(new void[__conv_EmplaceTest.sizeof], 5, var);
536     assert(z.i == 5);
537     assert(var == 7);
538 }
539 
540 // Test matching fields branch
541 @betterC
542 @system unittest
543 {
544     struct S { uint n; }
545     S s;
546     emplace!S(&s, 2U);
547     assert(s.n == 2);
548 }
549 
550 @betterC
551 @safe unittest
552 {
553     struct S { int a, b; this(int){} }
554     S s;
555     static assert(!__traits(compiles, emplace!S(&s, 2, 3)));
556 }
557 
558 @betterC
559 @system unittest
560 {
561     struct S { int a, b = 7; }
562     S s1 = void, s2 = void;
563 
564     emplace!S(&s1, 2);
565     assert(s1.a == 2 && s1.b == 7);
566 
567     emplace!S(&s2, 2, 3);
568     assert(s2.a == 2 && s2.b == 3);
569 }
570 
571 //opAssign
572 @betterC
573 @system unittest
574 {
575     static struct S
576     {
577         int i = 5;
578         void opAssign(int){assert(0);}
579         void opAssign(S){assert(0);}
580     }
581     S sa1 = void;
582     S sa2 = void;
583     S sb1 = S(1);
584     emplace(&sa1, sb1);
585     emplace(&sa2, 2);
586     assert(sa1.i == 1);
587     assert(sa2.i == 2);
588 }
589 
590 //postblit precedence
591 @betterC
592 @system unittest
593 {
594     //Works, but breaks in "-w -O" because of @@@9332@@@.
595     //Uncomment test when 9332 is fixed.
596     static struct S
597     {
598         int i;
599 
600         this(S other){assert(false);}
601         this(int i){this.i = i;}
602         this(this){}
603     }
604     S a = void;
605     assert(is(typeof({S b = a;})));    //Postblit
606     assert(is(typeof({S b = S(a);}))); //Constructor
607     auto b = S(5);
608     emplace(&a, b);
609     assert(a.i == 5);
610 
611     static struct S2
612     {
613         int* p;
614         this(const S2){}
615     }
616     static assert(!is(immutable S2 : S2));
617     S2 s2 = void;
618     immutable is2 = (immutable S2).init;
619     emplace(&s2, is2);
620 }
621 
622 //nested structs and postblit
623 @system unittest
624 {
625     static struct S
626     {
627         int* p;
628         this(int i){p = [i].ptr;}
629         this(this)
630         {
631             if (p)
632                 p = [*p].ptr;
633         }
634     }
635     static struct SS
636     {
637         S s;
638         void opAssign(const SS)
639         {
640             assert(0);
641         }
642     }
643     SS ssa = void;
644     SS ssb = SS(S(5));
645     emplace(&ssa, ssb);
646     assert(*ssa.s.p == 5);
647     assert(ssa.s.p != ssb.s.p);
648 }
649 
650 //disabled postblit
651 @betterC
652 @system unittest
653 {
654     static struct S1
655     {
656         int i;
657         @disable this(this);
658     }
659     S1 s1 = void;
660     emplace(&s1, 1);
661     assert(s1.i == 1);
662     static assert(!__traits(compiles, emplace(&s1, s1))); // copy disabled
663     static assert(__traits(compiles, emplace(&s1, move(s1)))); // move not affected
664 
665     static struct S2
666     {
667         int i;
668         @disable this(this);
669         this(ref S2){}
670     }
671     S2 s2 = void;
672     //static assert(!__traits(compiles, emplace(&s2, 1)));
673     emplace(&s2, S2.init);
674 
675     static struct SS1
676     {
677         S1 s;
678     }
679     SS1 ss1 = void;
680     emplace(&ss1);
681     static assert(!__traits(compiles, emplace(&ss1, ss1))); // copying disabled
682     static assert(__traits(compiles, emplace(&ss1, move(ss1)))); // move unaffected
683 
684     static struct SS2
685     {
686         S2 s;
687     }
688     SS2 ss2 = void;
689     emplace(&ss2);
690     static assert(!__traits(compiles, emplace(&ss2, ss2))); // copying disabled
691     static assert(__traits(compiles, emplace(&ss2, SS2.init))); // move is OK
692 
693 
694     // SS1 sss1 = s1;      //This doesn't compile
695     // SS1 sss1 = SS1(s1); //This doesn't compile
696     // So emplace shouldn't compile either
697     static assert(!__traits(compiles, emplace(&sss1, s1)));
698     static assert(!__traits(compiles, emplace(&sss2, s2)));
699 }
700 
701 //Imutability
702 @betterC
703 @system unittest
704 {
705     //Castable immutability
706     {
707         static struct S1
708         {
709             int i;
710         }
711         static assert(is( immutable(S1) : S1));
712         S1 sa = void;
713         auto sb = immutable(S1)(5);
714         emplace(&sa, sb);
715         assert(sa.i == 5);
716     }
717     //Un-castable immutability
718     {
719         static struct S2
720         {
721             int* p;
722         }
723         static assert(!is(immutable(S2) : S2));
724         S2 sa = void;
725         auto sb = immutable(S2)(null);
726         assert(!__traits(compiles, emplace(&sa, sb)));
727     }
728 }
729 
730 @betterC
731 @system unittest
732 {
733     static struct S
734     {
735         immutable int i;
736         immutable(int)* j;
737     }
738     S s = void;
739     emplace(&s, 1, null);
740     emplace(&s, 2, &s.i);
741     assert(s is S(2, &s.i));
742 }
743 
744 //Context pointer
745 @system unittest
746 {
747     int i = 0;
748     {
749         struct S1
750         {
751             void foo(){++i;}
752         }
753         S1 sa = void;
754         S1 sb;
755         emplace(&sa, sb);
756         sa.foo();
757         assert(i == 1);
758     }
759     {
760         struct S2
761         {
762             void foo(){++i;}
763             this(this){}
764         }
765         S2 sa = void;
766         S2 sb;
767         emplace(&sa, sb);
768         sa.foo();
769         assert(i == 2);
770     }
771 }
772 
773 //Alias this
774 @betterC
775 @system unittest
776 {
777     static struct S
778     {
779         int i;
780     }
781     //By Ref
782     {
783         static struct SS1
784         {
785             int j;
786             S s;
787             alias s this;
788         }
789         S s = void;
790         SS1 ss = SS1(1, S(2));
791         emplace(&s, ss);
792         assert(s.i == 2);
793     }
794     //By Value
795     {
796         static struct SS2
797         {
798             int j;
799             S s;
800             S foo() @property{return s;}
801             alias foo this;
802         }
803         S s = void;
804         SS2 ss = SS2(1, S(2));
805         emplace(&s, ss);
806         assert(s.i == 2);
807     }
808 }
809 
810 version (CoreUnittest)
811 {
812     //Ambiguity
813     private struct __std_conv_S
814     {
815         int i;
816         this(__std_conv_SS ss)         {assert(0);}
817         static opCall(__std_conv_SS ss)
818         {
819             __std_conv_S s; s.i = ss.j;
820             return s;
821         }
822     }
823     private struct __std_conv_SS
824     {
825         int j;
826         __std_conv_S s;
827         ref __std_conv_S foo() return @property {s.i = j; return s;}
828         alias foo this;
829     }
830 }
831 
832 @system unittest
833 {
834     static assert(is(__std_conv_SS : __std_conv_S));
835     __std_conv_S s = void;
836     __std_conv_SS ss = __std_conv_SS(1);
837 
838     __std_conv_S sTest1 = ss; //this calls "SS alias this" (and not "S.this(SS)")
839     emplace(&s, ss); //"alias this" should take precedence in emplace over "opCall"
840     assert(s.i == 1);
841 }
842 
843 //Nested classes
844 @system unittest
845 {
846     class A{}
847     static struct S
848     {
849         A a;
850     }
851     S s1 = void;
852     S s2 = S(new A);
853     emplace(&s1, s2);
854     assert(s1.a is s2.a);
855 }
856 
857 //safety & nothrow & CTFE
858 @betterC
859 @system unittest
860 {
861     //emplace should be safe for anything with no elaborate opassign
862     static struct S1
863     {
864         int i;
865     }
866     static struct S2
867     {
868         int i;
869         this(int j)@safe nothrow{i = j;}
870     }
871 
872     int i;
873     S1 s1 = void;
874     S2 s2 = void;
875 
876     auto pi = &i;
877     auto ps1 = &s1;
878     auto ps2 = &s2;
879 
880     void foo() @safe nothrow
881     {
882         emplace(pi);
883         emplace(pi, 5);
884         emplace(ps1);
885         emplace(ps1, 5);
886         emplace(ps1, S1.init);
887         emplace(ps2);
888         emplace(ps2, 5);
889         emplace(ps2, S2.init);
890     }
891     foo();
892 
893     T bar(T)() @property
894     {
895         T t/+ = void+/; //CTFE void illegal
896         emplace(&t, 5);
897         return t;
898     }
899     // CTFE
900     enum a = bar!int;
901     static assert(a == 5);
902     enum b = bar!S1;
903     static assert(b.i == 5);
904     enum c = bar!S2;
905     static assert(c.i == 5);
906     // runtime
907     auto aa = bar!int;
908     assert(aa == 5);
909     auto bb = bar!S1;
910     assert(bb.i == 5);
911     auto cc = bar!S2;
912     assert(cc.i == 5);
913 }
914 
915 @betterC
916 @system unittest
917 {
918     struct S
919     {
920         int[2] get(){return [1, 2];}
921         alias get this;
922     }
923     struct SS
924     {
925         int[2] ii;
926     }
927     struct ISS
928     {
929         int[2] ii;
930     }
931     S s;
932     SS ss = void;
933     ISS iss = void;
934     emplace(&ss, s);
935     emplace(&iss, s);
936     assert(ss.ii == [1, 2]);
937     assert(iss.ii == [1, 2]);
938 }
939 
940 //disable opAssign
941 @betterC
942 @system unittest
943 {
944     static struct S
945     {
946         @disable void opAssign(S);
947     }
948     S s;
949     emplace(&s, S.init);
950 }
951 
952 //opCall
953 @betterC
954 @system unittest
955 {
956     int i;
957     //Without constructor
958     {
959         static struct S1
960         {
961             int i;
962             static S1 opCall(int*){assert(0);}
963         }
964         S1 s = void;
965         static assert(!__traits(compiles, emplace(&s,  1)));
966     }
967     //With constructor
968     {
969         static struct S2
970         {
971             int i = 0;
972             static S2 opCall(int*){assert(0);}
973             static S2 opCall(int){assert(0);}
974             this(int i){this.i = i;}
975         }
976         S2 s = void;
977         emplace(&s,  1);
978         assert(s.i == 1);
979     }
980     //With postblit ambiguity
981     {
982         static struct S3
983         {
984             int i = 0;
985             static S3 opCall(ref S3){assert(0);}
986         }
987         S3 s = void;
988         emplace(&s, S3.init);
989     }
990 }
991 
992 //static arrays
993 @system unittest
994 {
995     static struct S
996     {
997         int[2] ii;
998     }
999     static struct IS
1000     {
1001         immutable int[2] ii;
1002     }
1003     int[2] ii;
1004     S  s   = void;
1005     IS ims = void;
1006     ubyte ub = 2;
1007     emplace(&s, ub);
1008     emplace(&s, ii);
1009     emplace(&ims, ub);
1010     emplace(&ims, ii);
1011     uint[2] uu;
1012     static assert(!__traits(compiles, {S ss = S(uu);}));
1013     static assert(!__traits(compiles, emplace(&s, uu)));
1014 }
1015 
1016 @system unittest
1017 {
1018     int[2]  sii;
1019     int[2]  sii2;
1020     uint[2] uii;
1021     uint[2] uii2;
1022     emplace(&sii, 1);
1023     emplace(&sii, 1U);
1024     emplace(&uii, 1);
1025     emplace(&uii, 1U);
1026     emplace(&sii, sii2);
1027     //emplace(&sii, uii2); //Sorry, this implementation doesn't know how to...
1028     //emplace(&uii, sii2); //Sorry, this implementation doesn't know how to...
1029     emplace(&uii, uii2);
1030     emplace(&sii, sii2[]);
1031     //emplace(&sii, uii2[]); //Sorry, this implementation doesn't know how to...
1032     //emplace(&uii, sii2[]); //Sorry, this implementation doesn't know how to...
1033     emplace(&uii, uii2[]);
1034 }
1035 
1036 @system unittest
1037 {
1038     bool allowDestruction = false;
1039     struct S
1040     {
1041         int i;
1042         this(this){}
1043         ~this(){assert(allowDestruction);}
1044     }
1045     S s = S(1);
1046     S[2] ss1 = void;
1047     S[2] ss2 = void;
1048     S[2] ss3 = void;
1049     emplace(&ss1, s);
1050     emplace(&ss2, ss1);
1051     emplace(&ss3, ss2[]);
1052     assert(ss1[1] == s);
1053     assert(ss2[1] == s);
1054     assert(ss3[1] == s);
1055     allowDestruction = true;
1056 }
1057 
1058 @system unittest
1059 {
1060     //Checks postblit, construction, and context pointer
1061     int count = 0;
1062     struct S
1063     {
1064         this(this)
1065         {
1066             ++count;
1067         }
1068         ~this()
1069         {
1070             --count;
1071         }
1072     }
1073 
1074     S s;
1075     {
1076         S[4] ss = void;
1077         emplace(&ss, s);
1078         assert(count == 4);
1079     }
1080     assert(count == 0);
1081 }
1082 
1083 @system unittest
1084 {
1085     struct S
1086     {
1087         int i;
1088     }
1089     S s;
1090     S[2][2][2] sss = void;
1091     emplace(&sss, s);
1092 }
1093 
1094 @system unittest //Constness
1095 {
1096     import core.internal.lifetime : emplaceRef;
1097 
1098     int a = void;
1099     emplaceRef!(const int)(a, 5);
1100 
1101     immutable i = 5;
1102     const(int)* p = void;
1103     emplaceRef!(const int*)(p, &i);
1104 
1105     struct S
1106     {
1107         int* p;
1108     }
1109     alias IS = immutable(S);
1110     S s = void;
1111     emplaceRef!IS(s, IS());
1112     S[2] ss = void;
1113     emplaceRef!(IS[2])(ss, IS());
1114 
1115     IS[2] iss = IS.init;
1116     emplaceRef!(IS[2])(ss, iss);
1117     emplaceRef!(IS[2])(ss, iss[]);
1118 }
1119 
1120 @betterC
1121 pure nothrow @safe @nogc unittest
1122 {
1123     import core.internal.lifetime : emplaceRef;
1124 
1125     int i;
1126     emplaceRef(i);
1127     emplaceRef!int(i);
1128     emplaceRef(i, 5);
1129     emplaceRef!int(i, 5);
1130 }
1131 
1132 // Test attribute propagation for UDTs
1133 pure nothrow @safe /* @nogc */ unittest
1134 {
1135     import core.internal.lifetime : emplaceRef;
1136 
1137     static struct Safe
1138     {
1139         this(this) pure nothrow @safe @nogc {}
1140     }
1141 
1142     Safe safe = void;
1143     emplaceRef(safe, Safe());
1144 
1145     Safe[1] safeArr = [Safe()];
1146     Safe[1] uninitializedSafeArr = void;
1147     emplaceRef(uninitializedSafeArr, safe);
1148     emplaceRef(uninitializedSafeArr, safeArr);
1149 
1150     static struct Unsafe
1151     {
1152         this(this) @system {}
1153     }
1154 
1155     Unsafe unsafe = void;
1156     static assert(!__traits(compiles, emplaceRef(unsafe, unsafe)));
1157 
1158     Unsafe[1] unsafeArr = [Unsafe()];
1159     Unsafe[1] uninitializedUnsafeArr = void;
1160     static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafe)));
1161     static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafeArr)));
1162 }
1163 
1164 @betterC
1165 @system unittest
1166 {
1167     // Issue 15313
1168     static struct Node
1169     {
1170         int payload;
1171         Node* next;
1172         uint refs;
1173     }
1174 
1175     import core.stdc.stdlib : malloc;
1176     void[] buf = malloc(Node.sizeof)[0 .. Node.sizeof];
1177 
1178     const Node* n = emplace!(const Node)(buf, 42, null, 10);
1179     assert(n.payload == 42);
1180     assert(n.next == null);
1181     assert(n.refs == 10);
1182 }
1183 
1184 @system unittest
1185 {
1186     class A
1187     {
1188         int x = 5;
1189         int y = 42;
1190         this(int z)
1191         {
1192             assert(x == 5 && y == 42);
1193             x = y = z;
1194         }
1195     }
1196     void[] buf;
1197 
1198     static align(__traits(classInstanceAlignment, A)) byte[__traits(classInstanceSize, A)] sbuf;
1199     buf = sbuf[];
1200     auto a = emplace!A(buf, 55);
1201     assert(a.x == 55 && a.y == 55);
1202 
1203     // emplace in bigger buffer
1204     buf = new byte[](__traits(classInstanceSize, A) + 10);
1205     a = emplace!A(buf, 55);
1206     assert(a.x == 55 && a.y == 55);
1207 
1208     // need ctor args
1209     static assert(!is(typeof(emplace!A(buf))));
1210 }
1211 
1212 //constructor arguments forwarding
1213 @betterC
1214 @system unittest
1215 {
1216     static struct S
1217     {
1218         this()(auto ref long arg)
1219         {
1220             // assert that arg is an lvalue
1221             static assert(__traits(isRef, arg));
1222         }
1223         this()(auto ref double arg)
1224             // assert that arg is an rvalue
1225         {
1226             static assert(!__traits(isRef, arg));
1227         }
1228     }
1229     S obj = void;
1230     long i;
1231     emplace(&obj, i);   // lvalue
1232     emplace(&obj, 0.0); // rvalue
1233 }
1234 // Bulk of emplace unittests ends here
1235 
1236 /**
1237  * Emplaces a copy of the specified source value into uninitialized memory,
1238  * i.e., simulates `T target = source` copy-construction for cases where the
1239  * target memory is already allocated and to be initialized with a copy.
1240  *
1241  * Params:
1242  *   source = value to be copied into target
1243  *   target = uninitialized value to be initialized with a copy of source
1244  */
1245 void copyEmplace(S, T)(ref S source, ref T target) @system
1246     if (is(immutable S == immutable T))
1247 {
1248     import core.internal.traits : BaseElemOf, hasElaborateCopyConstructor, Unconst, Unqual;
1249 
1250     // cannot have the following as simple template constraint due to nested-struct special case...
1251     static if (!__traits(compiles, (ref S src) { T tgt = src; }))
1252     {
1253         alias B = BaseElemOf!T;
1254         enum isNestedStruct = is(B == struct) && __traits(isNested, B);
1255         static assert(isNestedStruct, "cannot copy-construct " ~ T.stringof ~ " from " ~ S.stringof);
1256     }
1257 
1258     void blit()
1259     {
1260         import core.stdc.string : memcpy;
1261         memcpy(cast(Unqual!(T)*) &target, cast(Unqual!(T)*) &source, T.sizeof);
1262     }
1263 
1264     static if (is(T == struct))
1265     {
1266         static if (__traits(hasPostblit, T))
1267         {
1268             blit();
1269             (cast() target).__xpostblit();
1270         }
1271         else static if (__traits(hasCopyConstructor, T))
1272         {
1273             // https://issues.dlang.org/show_bug.cgi?id=22766
1274             import core.internal.lifetime : emplaceInitializer;
1275             emplaceInitializer(*(cast(Unqual!T*)&target));
1276             static if (__traits(isNested, T))
1277             {
1278                  // copy context pointer
1279                 *(cast(void**) &target.tupleof[$-1]) = cast(void*) source.tupleof[$-1];
1280             }
1281             target.__ctor(source); // invoke copy ctor
1282         }
1283         else
1284         {
1285             blit(); // no opAssign
1286         }
1287     }
1288     else static if (is(T == E[n], E, size_t n))
1289     {
1290         static if (hasElaborateCopyConstructor!E)
1291         {
1292             size_t i;
1293             try
1294             {
1295                 for (i = 0; i < n; i++)
1296                     copyEmplace(source[i], target[i]);
1297             }
1298             catch (Exception e)
1299             {
1300                 // destroy, in reverse order, what we've constructed so far
1301                 while (i--)
1302                     destroy(*cast(Unconst!(E)*) &target[i]);
1303                 throw e;
1304             }
1305         }
1306         else // trivial copy
1307         {
1308             blit(); // all elements at once
1309         }
1310     }
1311     else
1312     {
1313         *cast(Unconst!(T)*) &target = *cast(Unconst!(T)*) &source;
1314     }
1315 }
1316 
1317 ///
1318 @betterC
1319 @system pure nothrow @nogc unittest
1320 {
1321     int source = 123;
1322     int target = void;
1323     copyEmplace(source, target);
1324     assert(target == 123);
1325 }
1326 
1327 ///
1328 @betterC
1329 @system pure nothrow @nogc unittest
1330 {
1331     immutable int[1][1] source = [ [123] ];
1332     immutable int[1][1] target = void;
1333     copyEmplace(source, target);
1334     assert(target[0][0] == 123);
1335 }
1336 
1337 ///
1338 @betterC
1339 @system pure nothrow @nogc unittest
1340 {
1341     struct S
1342     {
1343         int x;
1344         void opAssign(const scope ref S rhs) @safe pure nothrow @nogc
1345         {
1346             assert(0);
1347         }
1348     }
1349 
1350     S source = S(42);
1351     S target = void;
1352     copyEmplace(source, target);
1353     assert(target.x == 42);
1354 }
1355 
1356 // preserve shared-ness
1357 @system pure nothrow unittest
1358 {
1359     auto s = new Object();
1360     auto ss = new shared Object();
1361 
1362     Object t;
1363     shared Object st;
1364 
1365     copyEmplace(s, t);
1366     assert(t is s);
1367 
1368     copyEmplace(ss, st);
1369     assert(st is ss);
1370 
1371     static assert(!__traits(compiles, copyEmplace(s, st)));
1372     static assert(!__traits(compiles, copyEmplace(ss, t)));
1373 }
1374 
1375 // https://issues.dlang.org/show_bug.cgi?id=22766
1376 @system pure nothrow @nogc unittest
1377 {
1378     static struct S
1379     {
1380         @disable this();
1381         this(int) @safe pure nothrow @nogc{}
1382         this(ref const(S) other) @safe pure nothrow @nogc {}
1383     }
1384 
1385     S s1 = S(1);
1386     S s2 = void;
1387     copyEmplace(s1, s2);
1388     assert(s2 == S(1));
1389 }
1390 
1391 version (DigitalMars) version (X86) version (Posix) version = DMD_X86_Posix;
1392 
1393 // don't violate immutability for reference types
1394 @system pure nothrow unittest
1395 {
1396     auto s = new Object();
1397     auto si = new immutable Object();
1398 
1399     Object t;
1400     immutable Object ti;
1401 
1402     copyEmplace(s, t);
1403     assert(t is s);
1404 
1405     copyEmplace(si, ti);
1406     version (DMD_X86_Posix) { /* wrongly fails without -O */ } else
1407         assert(ti is si);
1408 
1409     static assert(!__traits(compiles, copyEmplace(s, ti)));
1410     static assert(!__traits(compiles, copyEmplace(si, t)));
1411 }
1412 
1413 version (CoreUnittest)
1414 {
1415     private void testCopyEmplace(S, T)(const scope T* expected = null)
1416     {
1417         S source;
1418         T target = void;
1419         copyEmplace(source, target);
1420         if (expected)
1421             assert(target == *expected);
1422         else
1423         {
1424             T expectedCopy = source;
1425             assert(target == expectedCopy);
1426         }
1427     }
1428 }
1429 
1430 // postblit
1431 @system pure nothrow @nogc unittest
1432 {
1433     static struct S
1434     {
1435         @safe pure nothrow @nogc:
1436         int x = 42;
1437         this(this) { x += 10; }
1438     }
1439 
1440     testCopyEmplace!(S, S)();
1441     testCopyEmplace!(immutable S, S)();
1442     testCopyEmplace!(S, immutable S)();
1443     testCopyEmplace!(immutable S, immutable S)();
1444 
1445     testCopyEmplace!(S[1], S[1])();
1446     testCopyEmplace!(immutable S[1], S[1])();
1447 
1448     // copying to an immutable static array works, but `T expected = source`
1449     // wrongly ignores the postblit: https://issues.dlang.org/show_bug.cgi?id=8950
1450     immutable S[1] expectedImmutable = [S(52)];
1451     testCopyEmplace!(S[1], immutable S[1])(&expectedImmutable);
1452     testCopyEmplace!(immutable S[1], immutable S[1])(&expectedImmutable);
1453 }
1454 
1455 // copy constructors
1456 @system pure nothrow @nogc unittest
1457 {
1458     static struct S
1459     {
1460         @safe pure nothrow @nogc:
1461         int x = 42;
1462         this(int x) { this.x = x; }
1463         this(const scope ref S rhs) { x = rhs.x + 10; }
1464         this(const scope ref S rhs) immutable { x = rhs.x + 20; }
1465     }
1466 
1467     testCopyEmplace!(S, S)();
1468     testCopyEmplace!(immutable S, S)();
1469     testCopyEmplace!(S, immutable S)();
1470     testCopyEmplace!(immutable S, immutable S)();
1471 
1472     // static arrays work, but `T expected = source` wrongly ignores copy ctors
1473     // https://issues.dlang.org/show_bug.cgi?id=20365
1474     S[1] expectedMutable = [S(52)];
1475     immutable S[1] expectedImmutable = [immutable S(62)];
1476     testCopyEmplace!(S[1], S[1])(&expectedMutable);
1477     testCopyEmplace!(immutable S[1], S[1])(&expectedMutable);
1478     testCopyEmplace!(S[1], immutable S[1])(&expectedImmutable);
1479     testCopyEmplace!(immutable S[1], immutable S[1])(&expectedImmutable);
1480 }
1481 
1482 // copy constructor in nested struct
1483 @system pure nothrow unittest
1484 {
1485     int copies;
1486     struct S
1487     {
1488         @safe pure nothrow @nogc:
1489         size_t x = 42;
1490         this(size_t x) { this.x = x; }
1491         this(const scope ref S rhs)
1492         {
1493             assert(x == 42); // T.init
1494             x = rhs.x;
1495             ++copies;
1496         }
1497     }
1498 
1499     {
1500         copies = 0;
1501         S source = S(123);
1502         immutable S target = void;
1503         copyEmplace(source, target);
1504         assert(target is source);
1505         assert(copies == 1);
1506     }
1507 
1508     {
1509         copies = 0;
1510         immutable S[1] source = [immutable S(456)];
1511         S[1] target = void;
1512         copyEmplace(source, target);
1513         assert(target[0] is source[0]);
1514         assert(copies == 1);
1515     }
1516 }
1517 
1518 // destruction of partially copied static array
1519 @system unittest
1520 {
1521     static struct S
1522     {
1523         __gshared int[] deletions;
1524         int x;
1525         this(this) { if (x == 5) throw new Exception(""); }
1526         ~this() { deletions ~= x; }
1527     }
1528 
1529     alias T = immutable S[3][2];
1530     T source = [ [S(1), S(2), S(3)], [S(4), S(5), S(6)] ];
1531     T target = void;
1532     try
1533     {
1534         copyEmplace(source, target);
1535         assert(0);
1536     }
1537     catch (Exception)
1538     {
1539         static immutable expectedDeletions = [ 4, 3, 2, 1 ];
1540         version (DigitalMars)
1541         {
1542             assert(S.deletions == expectedDeletions ||
1543                    S.deletions == [ 4 ]); // FIXME: happens with -O
1544         }
1545         else
1546             assert(S.deletions == expectedDeletions);
1547     }
1548 }
1549 
1550 /**
1551 Forwards function arguments while keeping `out`, `ref`, and `lazy` on
1552 the parameters.
1553 
1554 Params:
1555     args = a parameter list or an $(REF AliasSeq,std,meta).
1556 Returns:
1557     An `AliasSeq` of `args` with `out`, `ref`, and `lazy` saved.
1558 */
1559 template forward(args...)
1560 {
1561     import core.internal.traits : AliasSeq;
1562 
1563     template fwd(alias arg)
1564     {
1565         // by ref || lazy || const/immutable
1566         static if (__traits(isRef,  arg) ||
1567                    __traits(isOut,  arg) ||
1568                    __traits(isLazy, arg) ||
1569                    !is(typeof(move(arg))))
1570             alias fwd = arg;
1571         // (r)value
1572         else
1573             @property auto fwd()
1574             {
1575                 version (DigitalMars) { /* @@BUG 23890@@ */ } else pragma(inline, true);
1576                 return move(arg);
1577             }
1578     }
1579 
1580     alias Result = AliasSeq!();
1581     static foreach (arg; args)
1582         Result = AliasSeq!(Result, fwd!arg);
1583     static if (Result.length == 1)
1584         alias forward = Result[0];
1585     else
1586         alias forward = Result;
1587 }
1588 
1589 ///
1590 @safe unittest
1591 {
1592     class C
1593     {
1594         static int foo(int n) { return 1; }
1595         static int foo(ref int n) { return 2; }
1596     }
1597 
1598     // with forward
1599     int bar()(auto ref int x) { return C.foo(forward!x); }
1600 
1601     // without forward
1602     int baz()(auto ref int x) { return C.foo(x); }
1603 
1604     int i;
1605     assert(bar(1) == 1);
1606     assert(bar(i) == 2);
1607 
1608     assert(baz(1) == 2);
1609     assert(baz(i) == 2);
1610 }
1611 
1612 ///
1613 @safe unittest
1614 {
1615     void foo(int n, ref string s) { s = null; foreach (i; 0 .. n) s ~= "Hello"; }
1616 
1617     // forwards all arguments which are bound to parameter tuple
1618     void bar(Args...)(auto ref Args args) { return foo(forward!args); }
1619 
1620     // forwards all arguments with swapping order
1621     void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }
1622 
1623     string s;
1624     bar(1, s);
1625     assert(s == "Hello");
1626     baz(s, 2);
1627     assert(s == "HelloHello");
1628 }
1629 
1630 @safe unittest
1631 {
1632     auto foo(TL...)(auto ref TL args)
1633     {
1634         string result = "";
1635         foreach (i, _; args)
1636         {
1637             //pragma(msg, "[",i,"] ", __traits(isRef, args[i]) ? "L" : "R");
1638             result ~= __traits(isRef, args[i]) ? "L" : "R";
1639         }
1640         return result;
1641     }
1642 
1643     string bar(TL...)(auto ref TL args)
1644     {
1645         return foo(forward!args);
1646     }
1647     string baz(TL...)(auto ref TL args)
1648     {
1649         int x;
1650         return foo(forward!args[3], forward!args[2], 1, forward!args[1], forward!args[0], x);
1651     }
1652 
1653     struct S {}
1654     S makeS(){ return S(); }
1655     int n;
1656     string s;
1657     assert(bar(S(), makeS(), n, s) == "RRLL");
1658     assert(baz(S(), makeS(), n, s) == "LLRRRL");
1659 }
1660 
1661 @betterC
1662 @safe unittest
1663 {
1664     ref int foo(return ref int a) { return a; }
1665     ref int bar(Args)(auto ref Args args)
1666     {
1667         return foo(forward!args);
1668     }
1669     static assert(!__traits(compiles, { auto x1 = bar(3); })); // case of NG
1670     int value = 3;
1671     auto x2 = bar(value); // case of OK
1672 }
1673 
1674 ///
1675 @betterC
1676 @safe unittest
1677 {
1678     struct X {
1679         int i;
1680         this(this)
1681         {
1682             ++i;
1683         }
1684     }
1685 
1686     struct Y
1687     {
1688         private X x_;
1689         this()(auto ref X x)
1690         {
1691             x_ = forward!x;
1692         }
1693     }
1694 
1695     struct Z
1696     {
1697         private const X x_;
1698         this()(auto ref X x)
1699         {
1700             x_ = forward!x;
1701         }
1702         this()(auto const ref X x)
1703         {
1704             x_ = forward!x;
1705         }
1706     }
1707 
1708     X x;
1709     const X cx;
1710     auto constX = (){ const X x; return x; };
1711     static assert(__traits(compiles, { Y y = x; }));
1712     static assert(__traits(compiles, { Y y = X(); }));
1713     static assert(!__traits(compiles, { Y y = cx; }));
1714     static assert(!__traits(compiles, { Y y = constX(); }));
1715     static assert(__traits(compiles, { Z z = x; }));
1716     static assert(__traits(compiles, { Z z = X(); }));
1717     static assert(__traits(compiles, { Z z = cx; }));
1718     static assert(__traits(compiles, { Z z = constX(); }));
1719 
1720 
1721     Y y1 = x;
1722     // ref lvalue, copy
1723     assert(y1.x_.i == 1);
1724     Y y2 = X();
1725     // rvalue, move
1726     assert(y2.x_.i == 0);
1727 
1728     Z z1 = x;
1729     // ref lvalue, copy
1730     assert(z1.x_.i == 1);
1731     Z z2 = X();
1732     // rvalue, move
1733     assert(z2.x_.i == 0);
1734     Z z3 = cx;
1735     // ref const lvalue, copy
1736     assert(z3.x_.i == 1);
1737     Z z4 = constX();
1738     // const rvalue, copy
1739     assert(z4.x_.i == 1);
1740 }
1741 
1742 // lazy -> lazy
1743 @betterC
1744 @safe unittest
1745 {
1746     int foo1(lazy int i) { return i; }
1747     int foo2(A)(auto ref A i) { return foo1(forward!i); }
1748     int foo3(lazy int i) { return foo2(i); }
1749 
1750     int numCalls = 0;
1751     assert(foo3({ ++numCalls; return 42; }()) == 42);
1752     assert(numCalls == 1);
1753 }
1754 
1755 // lazy -> non-lazy
1756 @betterC
1757 @safe unittest
1758 {
1759     int foo1(int a, int b) { return a + b; }
1760     int foo2(A...)(auto ref A args) { return foo1(forward!args); }
1761     int foo3(int a, lazy int b) { return foo2(a, b); }
1762 
1763     int numCalls;
1764     assert(foo3(11, { ++numCalls; return 31; }()) == 42);
1765     assert(numCalls == 1);
1766 }
1767 
1768 // non-lazy -> lazy
1769 @betterC
1770 @safe unittest
1771 {
1772     int foo1(int a, lazy int b) { return a + b; }
1773     int foo2(A...)(auto ref A args) { return foo1(forward!args); }
1774     int foo3(int a, int b) { return foo2(a, b); }
1775 
1776     assert(foo3(11, 31) == 42);
1777 }
1778 
1779 // out
1780 @betterC
1781 @safe unittest
1782 {
1783     void foo1(int a, out int b) { b = a; }
1784     void foo2(A...)(auto ref A args) { foo1(forward!args); }
1785     void foo3(int a, out int b) { foo2(a, b); }
1786 
1787     int b;
1788     foo3(42, b);
1789     assert(b == 42);
1790 }
1791 
1792 // move
1793 /**
1794 Moves `source` into `target`, via a destructive copy when necessary.
1795 
1796 If `T` is a struct with a destructor or postblit defined, source is reset
1797 to its `.init` value after it is moved into target, otherwise it is
1798 left unchanged.
1799 
1800 Preconditions:
1801 If source has internal pointers that point to itself and doesn't define
1802 opPostMove, it cannot be moved, and will trigger an assertion failure.
1803 
1804 Params:
1805     source = Data to copy.
1806     target = Where to copy into. The destructor, if any, is invoked before the
1807         copy is performed.
1808 */
1809 void move(T)(ref T source, ref T target)
1810 {
1811     moveImpl(target, source);
1812 }
1813 
1814 /// For non-struct types, `move` just performs `target = source`:
1815 @safe unittest
1816 {
1817     Object obj1 = new Object;
1818     Object obj2 = obj1;
1819     Object obj3;
1820 
1821     move(obj2, obj3);
1822     assert(obj3 is obj1);
1823     // obj2 unchanged
1824     assert(obj2 is obj1);
1825 }
1826 
1827 ///
1828 pure nothrow @safe @nogc unittest
1829 {
1830     // Structs without destructors are simply copied
1831     struct S1
1832     {
1833         int a = 1;
1834         int b = 2;
1835     }
1836     S1 s11 = { 10, 11 };
1837     S1 s12;
1838 
1839     move(s11, s12);
1840 
1841     assert(s12 == S1(10, 11));
1842     assert(s11 == s12);
1843 
1844     // But structs with destructors or postblits are reset to their .init value
1845     // after copying to the target.
1846     struct S2
1847     {
1848         int a = 1;
1849         int b = 2;
1850 
1851         ~this() pure nothrow @safe @nogc { }
1852     }
1853     S2 s21 = { 3, 4 };
1854     S2 s22;
1855 
1856     move(s21, s22);
1857 
1858     assert(s21 == S2(1, 2));
1859     assert(s22 == S2(3, 4));
1860 }
1861 
1862 @safe unittest
1863 {
1864     import core.internal.traits;
1865 
1866     assertCTFEable!((){
1867         Object obj1 = new Object;
1868         Object obj2 = obj1;
1869         Object obj3;
1870         move(obj2, obj3);
1871         assert(obj3 is obj1);
1872 
1873         static struct S1 { int a = 1, b = 2; }
1874         S1 s11 = { 10, 11 };
1875         S1 s12;
1876         move(s11, s12);
1877         assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
1878 
1879         static struct S2 { int a = 1; int * b; }
1880         S2 s21 = { 10, null };
1881         s21.b = new int;
1882         S2 s22;
1883         move(s21, s22);
1884         assert(s21 == s22);
1885     });
1886     // Issue 5661 test(1)
1887     static struct S3
1888     {
1889         static struct X { int n = 0; ~this(){n = 0;} }
1890         X x;
1891     }
1892     static assert(hasElaborateDestructor!S3);
1893     S3 s31, s32;
1894     s31.x.n = 1;
1895     move(s31, s32);
1896     assert(s31.x.n == 0);
1897     assert(s32.x.n == 1);
1898 
1899     // Issue 5661 test(2)
1900     static struct S4
1901     {
1902         static struct X { int n = 0; this(this){n = 0;} }
1903         X x;
1904     }
1905     static assert(hasElaborateCopyConstructor!S4);
1906     S4 s41, s42;
1907     s41.x.n = 1;
1908     move(s41, s42);
1909     assert(s41.x.n == 0);
1910     assert(s42.x.n == 1);
1911 
1912     // Issue 13990 test
1913     class S5;
1914 
1915     S5 s51;
1916     S5 s52 = s51;
1917     S5 s53;
1918     move(s52, s53);
1919     assert(s53 is s51);
1920 }
1921 
1922 /// Ditto
1923 T move(T)(return scope ref T source)
1924 {
1925     return moveImpl(source);
1926 }
1927 
1928 /// Non-copyable structs can still be moved:
1929 pure nothrow @safe @nogc unittest
1930 {
1931     struct S
1932     {
1933         int a = 1;
1934         @disable this(this);
1935         ~this() pure nothrow @safe @nogc {}
1936     }
1937     S s1;
1938     s1.a = 2;
1939     S s2 = move(s1);
1940     assert(s1.a == 1);
1941     assert(s2.a == 2);
1942 }
1943 
1944 // https://issues.dlang.org/show_bug.cgi?id=20869
1945 // `move` should propagate the attributes of `opPostMove`
1946 @system unittest
1947 {
1948     static struct S
1949     {
1950         void opPostMove(const ref S old) nothrow @system
1951         {
1952             __gshared int i;
1953             new int(i++); // Force @gc impure @system
1954         }
1955     }
1956 
1957     alias T = void function() @system nothrow;
1958     static assert(is(typeof({ S s; move(s); }) == T));
1959     static assert(is(typeof({ S s; move(s, s); }) == T));
1960 }
1961 
1962 private void moveImpl(T)(scope ref T target, return scope ref T source)
1963 {
1964     import core.internal.traits : hasElaborateDestructor;
1965 
1966     static if (is(T == struct))
1967     {
1968         //  Unsafe when compiling without -preview=dip1000
1969         if ((() @trusted => &source == &target)()) return;
1970         // Destroy target before overwriting it
1971         static if (hasElaborateDestructor!T) target.__xdtor();
1972     }
1973     // move and emplace source into target
1974     moveEmplaceImpl(target, source);
1975 }
1976 
1977 private T moveImpl(T)(return scope ref T source)
1978 {
1979     // Properly infer safety from moveEmplaceImpl as the implementation below
1980     // might void-initialize pointers in result and hence needs to be @trusted
1981     if (false) moveEmplaceImpl(source, source);
1982 
1983     return trustedMoveImpl(source);
1984 }
1985 
1986 private T trustedMoveImpl(T)(return scope ref T source) @trusted
1987 {
1988     T result = void;
1989     moveEmplaceImpl(result, source);
1990     return result;
1991 }
1992 
1993 @safe unittest
1994 {
1995     import core.internal.traits;
1996 
1997     assertCTFEable!((){
1998         Object obj1 = new Object;
1999         Object obj2 = obj1;
2000         Object obj3 = move(obj2);
2001         assert(obj3 is obj1);
2002 
2003         static struct S1 { int a = 1, b = 2; }
2004         S1 s11 = { 10, 11 };
2005         S1 s12 = move(s11);
2006         assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
2007 
2008         static struct S2 { int a = 1; int * b; }
2009         S2 s21 = { 10, null };
2010         s21.b = new int;
2011         S2 s22 = move(s21);
2012         assert(s21 == s22);
2013     });
2014 
2015     // Issue 5661 test(1)
2016     static struct S3
2017     {
2018         static struct X { int n = 0; ~this(){n = 0;} }
2019         X x;
2020     }
2021     static assert(hasElaborateDestructor!S3);
2022     S3 s31;
2023     s31.x.n = 1;
2024     S3 s32 = move(s31);
2025     assert(s31.x.n == 0);
2026     assert(s32.x.n == 1);
2027 
2028     // Issue 5661 test(2)
2029     static struct S4
2030     {
2031         static struct X { int n = 0; this(this){n = 0;} }
2032         X x;
2033     }
2034     static assert(hasElaborateCopyConstructor!S4);
2035     S4 s41;
2036     s41.x.n = 1;
2037     S4 s42 = move(s41);
2038     assert(s41.x.n == 0);
2039     assert(s42.x.n == 1);
2040 
2041     // Issue 13990 test
2042     class S5;
2043 
2044     S5 s51;
2045     S5 s52 = s51;
2046     S5 s53;
2047     s53 = move(s52);
2048     assert(s53 is s51);
2049 }
2050 
2051 @betterC
2052 @system unittest
2053 {
2054     static struct S { int n = 0; ~this() @system { n = 0; } }
2055     S a, b;
2056     static assert(!__traits(compiles, () @safe { move(a, b); }));
2057     static assert(!__traits(compiles, () @safe { move(a); }));
2058     a.n = 1;
2059     () @trusted { move(a, b); }();
2060     assert(a.n == 0);
2061     a.n = 1;
2062     () @trusted { move(a); }();
2063     assert(a.n == 0);
2064 }
2065 /+ this can't be tested in druntime, tests are still run in phobos
2066 @safe unittest//Issue 6217
2067 {
2068     import std.algorithm.iteration : map;
2069     auto x = map!"a"([1,2,3]);
2070     x = move(x);
2071 }
2072 +/
2073 @betterC
2074 @safe unittest// Issue 8055
2075 {
2076     static struct S
2077     {
2078         int x;
2079         ~this()
2080         {
2081             assert(x == 0);
2082         }
2083     }
2084     S foo(S s)
2085     {
2086         return move(s);
2087     }
2088     S a;
2089     a.x = 0;
2090     auto b = foo(a);
2091     assert(b.x == 0);
2092 }
2093 
2094 @system unittest// Issue 8057
2095 {
2096     int n = 10;
2097     struct S
2098     {
2099         int x;
2100         ~this()
2101         {
2102             // Access to enclosing scope
2103             assert(n == 10);
2104         }
2105     }
2106     S foo(S s)
2107     {
2108         // Move nested struct
2109         return move(s);
2110     }
2111     S a;
2112     a.x = 1;
2113     auto b = foo(a);
2114     assert(b.x == 1);
2115 
2116     // Regression 8171
2117     static struct Array(T)
2118     {
2119         // nested struct has no member
2120         struct Payload
2121         {
2122             ~this() {}
2123         }
2124     }
2125     Array!int.Payload x = void;
2126     move(x);
2127     move(x, x);
2128 }
2129 
2130 private enum bool hasContextPointers(T) = {
2131     static if (__traits(isStaticArray, T))
2132     {
2133         return hasContextPointers!(typeof(T.init[0]));
2134     }
2135     else static if (is(T == struct))
2136     {
2137         import core.internal.traits : anySatisfy;
2138         return __traits(isNested, T) || anySatisfy!(hasContextPointers, typeof(T.tupleof));
2139     }
2140     else return false;
2141 } ();
2142 
2143 @safe @nogc nothrow pure unittest
2144 {
2145     static assert(!hasContextPointers!int);
2146     static assert(!hasContextPointers!(void*));
2147 
2148     static struct S {}
2149     static assert(!hasContextPointers!S);
2150     static assert(!hasContextPointers!(S[1]));
2151 
2152     struct Nested
2153     {
2154         void foo() {}
2155     }
2156 
2157     static assert(hasContextPointers!Nested);
2158     static assert(hasContextPointers!(Nested[1]));
2159 
2160     static struct OneLevel
2161     {
2162         int before;
2163         Nested n;
2164         int after;
2165     }
2166 
2167     static assert(hasContextPointers!OneLevel);
2168     static assert(hasContextPointers!(OneLevel[1]));
2169 
2170     static struct TwoLevels
2171     {
2172         int before;
2173         OneLevel o;
2174         int after;
2175     }
2176 
2177     static assert(hasContextPointers!TwoLevels);
2178     static assert(hasContextPointers!(TwoLevels[1]));
2179 
2180     union U
2181     {
2182         Nested n;
2183     }
2184 
2185     // unions can have false positives, so this query ignores them
2186     static assert(!hasContextPointers!U);
2187 }
2188 
2189 // target must be first-parameter, because in void-functions DMD + dip1000 allows it to take the place of a return-scope
2190 private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
2191 {
2192     // TODO: this assert pulls in half of phobos. we need to work out an alternative assert strategy.
2193 //    static if (!is(T == class) && hasAliasing!T) if (!__ctfe)
2194 //    {
2195 //        import std.exception : doesPointTo;
2196 //        assert(!doesPointTo(source, source) && !hasElaborateMove!T),
2197 //              "Cannot move object with internal pointer unless `opPostMove` is defined.");
2198 //    }
2199 
2200     import core.internal.traits : hasElaborateAssign, isAssignable, hasElaborateMove,
2201                                   hasElaborateDestructor, hasElaborateCopyConstructor;
2202     static if (is(T == struct))
2203     {
2204 
2205         //  Unsafe when compiling without -preview=dip1000
2206         assert((() @trusted => &source !is &target)(), "source and target must not be identical");
2207 
2208         static if (hasElaborateAssign!T || !isAssignable!T)
2209         {
2210             import core.stdc.string : memcpy;
2211             () @trusted { memcpy(&target, &source, T.sizeof); }();
2212         }
2213         else
2214             target = source;
2215 
2216         static if (hasElaborateMove!T)
2217             __move_post_blt(target, source);
2218 
2219         // If the source defines a destructor or a postblit hook, we must obliterate the
2220         // object in order to avoid double freeing and undue aliasing
2221         static if (hasElaborateDestructor!T || hasElaborateCopyConstructor!T)
2222         {
2223             // If there are members that are nested structs, we must take care
2224             // not to erase any context pointers, so we might have to recurse
2225             static if (__traits(isZeroInit, T))
2226                 wipe(source);
2227             else
2228                 wipe(source, ref () @trusted { return *cast(immutable(T)*) __traits(initSymbol, T).ptr; } ());
2229         }
2230     }
2231     else static if (__traits(isStaticArray, T))
2232     {
2233         static if (T.length)
2234         {
2235             static if (!hasElaborateMove!T &&
2236                        !hasElaborateDestructor!T &&
2237                        !hasElaborateCopyConstructor!T)
2238             {
2239                 // Single blit if no special per-instance handling is required
2240                 () @trusted
2241                 {
2242                     assert(source.ptr !is target.ptr, "source and target must not be identical");
2243                     *cast(ubyte[T.sizeof]*) &target = *cast(ubyte[T.sizeof]*) &source;
2244                 } ();
2245             }
2246             else
2247             {
2248                 for (size_t i = 0; i < source.length; ++i)
2249                     moveEmplaceImpl(target[i], source[i]);
2250             }
2251         }
2252     }
2253     else
2254     {
2255         // Primitive data (including pointers and arrays) or class -
2256         // assignment works great
2257         target = source;
2258     }
2259 }
2260 
2261 /**
2262  * Similar to $(LREF move) but assumes `target` is uninitialized. This
2263  * is more efficient because `source` can be blitted over `target`
2264  * without destroying or initializing it first.
2265  *
2266  * Params:
2267  *   source = value to be moved into target
2268  *   target = uninitialized value to be filled by source
2269  */
2270 void moveEmplace(T)(ref T source, ref T target) @system
2271 {
2272     moveEmplaceImpl(target, source);
2273 }
2274 
2275 ///
2276 @betterC
2277 pure nothrow @nogc @system unittest
2278 {
2279     static struct Foo
2280     {
2281     pure nothrow @nogc:
2282         this(int* ptr) { _ptr = ptr; }
2283         ~this() { if (_ptr) ++*_ptr; }
2284         int* _ptr;
2285     }
2286 
2287     int val;
2288     Foo foo1 = void; // uninitialized
2289     auto foo2 = Foo(&val); // initialized
2290     assert(foo2._ptr is &val);
2291 
2292     // Using `move(foo2, foo1)` would have an undefined effect because it would destroy
2293     // the uninitialized foo1.
2294     // moveEmplace directly overwrites foo1 without destroying or initializing it first.
2295     moveEmplace(foo2, foo1);
2296     assert(foo1._ptr is &val);
2297     assert(foo2._ptr is null);
2298     assert(val == 0);
2299 }
2300 
2301 @betterC
2302 pure nothrow @nogc @system unittest
2303 {
2304     static struct Foo
2305     {
2306     pure nothrow @nogc:
2307         this(int* ptr) { _ptr = ptr; }
2308         ~this() { if (_ptr) ++*_ptr; }
2309         int* _ptr;
2310     }
2311 
2312     int val;
2313     {
2314         Foo[1] foo1 = void; // uninitialized
2315         Foo[1] foo2 = [Foo(&val)];// initialized
2316         assert(foo2[0]._ptr is &val);
2317 
2318         // Using `move(foo2, foo1)` would have an undefined effect because it would destroy
2319         // the uninitialized foo1.
2320         // moveEmplace directly overwrites foo1 without destroying or initializing it first.
2321         moveEmplace(foo2, foo1);
2322         assert(foo1[0]._ptr is &val);
2323         assert(foo2[0]._ptr is null);
2324         assert(val == 0);
2325     }
2326     assert(val == 1);
2327 }
2328 
2329 // https://issues.dlang.org/show_bug.cgi?id=18913
2330 @safe unittest
2331 {
2332     static struct NoCopy
2333     {
2334         int payload;
2335         ~this() { }
2336         @disable this(this);
2337     }
2338 
2339     static void f(NoCopy[2]) { }
2340 
2341     NoCopy[2] ncarray = [ NoCopy(1), NoCopy(2) ];
2342 
2343     static assert(!__traits(compiles, f(ncarray)));
2344     f(move(ncarray));
2345 }
2346 
2347 //debug = PRINTF;
2348 
2349 debug(PRINTF)
2350 {
2351     import core.stdc.stdio;
2352 }
2353 
2354 /// Implementation of `_d_delstruct` and `_d_delstructTrace`
2355 template _d_delstructImpl(T)
2356 {
2357     private void _d_delstructImpure(ref T p)
2358     {
2359         debug(PRINTF) printf("_d_delstruct(%p)\n", p);
2360 
2361         import core.memory : GC;
2362 
2363         destroy(*p);
2364         GC.free(p);
2365         p = null;
2366     }
2367 
2368     /**
2369      * This is called for a delete statement where the value being deleted is a
2370      * pointer to a struct with a destructor but doesn't have an overloaded
2371      * `delete` operator.
2372      *
2373      * Params:
2374      *   p = pointer to the value to be deleted
2375      *
2376      * Bugs:
2377      *   This function template was ported from a much older runtime hook that
2378      *   bypassed safety, purity, and throwabilty checks. To prevent breaking
2379      *   existing code, this function template is temporarily declared
2380      *   `@trusted` until the implementation can be brought up to modern D
2381      *   expectations.
2382      */
2383     void _d_delstruct(ref T p) @trusted @nogc pure nothrow
2384     {
2385         if (p)
2386         {
2387             alias Type = void function(ref T P) @nogc pure nothrow;
2388             (cast(Type) &_d_delstructImpure)(p);
2389         }
2390     }
2391 
2392     version (D_ProfileGC)
2393     {
2394         import core.internal.array.utils : _d_HookTraceImpl;
2395 
2396         private enum errorMessage = "Cannot delete struct if compiling without support for runtime type information!";
2397 
2398         /**
2399          * TraceGC wrapper around $(REF _d_delstruct, core,lifetime,_d_delstructImpl).
2400          *
2401          * Bugs:
2402          *   This function template was ported from a much older runtime hook that
2403          *   bypassed safety, purity, and throwabilty checks. To prevent breaking
2404          *   existing code, this function template is temporarily declared
2405          *   `@trusted` until the implementation can be brought up to modern D
2406          *   expectations.
2407          */
2408         alias _d_delstructTrace = _d_HookTraceImpl!(T, _d_delstruct, errorMessage);
2409     }
2410 }
2411 
2412 @system pure nothrow unittest
2413 {
2414     int dtors = 0;
2415     struct S { ~this() nothrow { ++dtors; } }
2416 
2417     S *s = new S();
2418     _d_delstructImpl!(typeof(s))._d_delstruct(s);
2419 
2420     assert(s == null);
2421     assert(dtors == 1);
2422 }
2423 
2424 @system pure unittest
2425 {
2426     int innerDtors = 0;
2427     int outerDtors = 0;
2428 
2429     struct Inner { ~this() { ++innerDtors; } }
2430     struct Outer
2431     {
2432         Inner *i1;
2433         Inner *i2;
2434 
2435         this(int x)
2436         {
2437             i1 = new Inner();
2438             i2 = new Inner();
2439         }
2440 
2441         ~this()
2442         {
2443             ++outerDtors;
2444 
2445             _d_delstructImpl!(typeof(i1))._d_delstruct(i1);
2446             assert(i1 == null);
2447 
2448            _d_delstructImpl!(typeof(i2))._d_delstruct(i2);
2449             assert(i2 == null);
2450         }
2451     }
2452 
2453     Outer *o = new Outer(0);
2454     _d_delstructImpl!(typeof(o))._d_delstruct(o);
2455 
2456     assert(o == null);
2457     assert(innerDtors == 2);
2458     assert(outerDtors == 1);
2459 }
2460 
2461 // https://issues.dlang.org/show_bug.cgi?id=25552
2462 pure nothrow @system unittest
2463 {
2464     int i;
2465     struct Nested
2466     {
2467     pure nothrow @nogc:
2468         char[1] arr; // char.init is not 0
2469         ~this() { ++i; }
2470     }
2471 
2472     {
2473         Nested[1] dst = void;
2474         Nested[1] src = [Nested(['a'])];
2475 
2476         moveEmplace(src, dst);
2477         assert(i == 0);
2478         assert(dst[0].arr == ['a']);
2479         assert(src[0].arr == [char.init]);
2480         assert(dst[0].tupleof[$-1] is src[0].tupleof[$-1]);
2481     }
2482     assert(i == 2);
2483 }
2484 
2485 // https://issues.dlang.org/show_bug.cgi?id=25552
2486 @safe unittest
2487 {
2488     int i;
2489     struct Nested
2490     {
2491         ~this() { ++i; }
2492     }
2493 
2494     static struct NotNested
2495     {
2496         Nested n;
2497     }
2498 
2499     static struct Deep
2500     {
2501         NotNested nn;
2502     }
2503 
2504     static struct Deeper
2505     {
2506         NotNested[1] nn;
2507     }
2508 
2509     static assert(__traits(isZeroInit, Nested));
2510     static assert(__traits(isZeroInit, NotNested));
2511     static assert(__traits(isZeroInit, Deep));
2512     static assert(__traits(isZeroInit, Deeper));
2513 
2514     {
2515         auto a = NotNested(Nested());
2516         assert(a.n.tupleof[$-1]);
2517         auto b = move(a);
2518         assert(b.n.tupleof[$-1]);
2519         assert(a.n.tupleof[$-1] is b.n.tupleof[$-1]);
2520 
2521         auto c = Deep(NotNested(Nested()));
2522         auto d = move(c);
2523         assert(d.nn.n.tupleof[$-1]);
2524         assert(c.nn.n.tupleof[$-1] is d.nn.n.tupleof[$-1]);
2525 
2526         auto e = Deeper([NotNested(Nested())]);
2527         auto f = move(e);
2528         assert(f.nn[0].n.tupleof[$-1]);
2529         assert(e.nn[0].n.tupleof[$-1] is f.nn[0].n.tupleof[$-1]);
2530     }
2531     assert(i == 6);
2532 }
2533 
2534 // https://issues.dlang.org/show_bug.cgi?id=25552
2535 @safe unittest
2536 {
2537     int i;
2538     struct Nested
2539     {
2540         align(32) // better still find context pointer correctly!
2541         int[3] stuff = [0, 1, 2];
2542         ~this() { ++i; }
2543     }
2544 
2545     static struct NoAssign
2546     {
2547         int value;
2548         @disable void opAssign(typeof(this));
2549     }
2550 
2551     static struct NotNested
2552     {
2553         int before = 42;
2554         align(Nested.alignof * 4) // better still find context pointer correctly!
2555         Nested n;
2556         auto after = NoAssign(43);
2557     }
2558 
2559     static struct Deep
2560     {
2561         NotNested nn;
2562     }
2563 
2564     static struct Deeper
2565     {
2566         NotNested[1] nn;
2567     }
2568 
2569     static assert(!__traits(isZeroInit, Nested));
2570     static assert(!__traits(isZeroInit, NotNested));
2571     static assert(!__traits(isZeroInit, Deep));
2572     static assert(!__traits(isZeroInit, Deeper));
2573 
2574     {
2575         auto a = NotNested(1, Nested([3, 4, 5]), NoAssign(2));
2576         auto b = move(a);
2577         assert(b.n.tupleof[$-1]);
2578         assert(a.n.tupleof[$-1] is b.n.tupleof[$-1]);
2579         assert(a.n.stuff == [0, 1, 2]);
2580         assert(a.before == 42);
2581         assert(a.after == NoAssign(43));
2582 
2583         auto c = Deep(NotNested(1, Nested([3, 4, 5]), NoAssign(2)));
2584         auto d = move(c);
2585         assert(d.nn.n.tupleof[$-1]);
2586         assert(c.nn.n.tupleof[$-1] is d.nn.n.tupleof[$-1]);
2587         assert(c.nn.n.stuff == [0, 1, 2]);
2588         assert(c.nn.before == 42);
2589         assert(c.nn.after == NoAssign(43));
2590 
2591         auto e = Deeper([NotNested(1, Nested([3, 4, 5]), NoAssign(2))]);
2592         auto f = move(e);
2593         assert(f.nn[0].n.tupleof[$-1]);
2594         assert(e.nn[0].n.tupleof[$-1] is f.nn[0].n.tupleof[$-1]);
2595         assert(e.nn[0].n.stuff == [0, 1, 2]);
2596         assert(e.nn[0].before == 42);
2597         assert(e.nn[0].after == NoAssign(43));
2598     }
2599     assert(i == 6);
2600 }
2601 
2602 // wipes source after moving
2603 pragma(inline, true)
2604 private void wipe(T, Init...)(return scope ref T source, ref const scope Init initializer) @trusted
2605 if (!Init.length ||
2606     ((Init.length == 1) && (is(immutable T == immutable Init[0]))))
2607 {
2608     static if (__traits(isStaticArray, T) && hasContextPointers!T)
2609     {
2610         for (auto i = 0; i < T.length; i++)
2611             static if (Init.length)
2612                 wipe(source[i], initializer[0][i]);
2613             else
2614                 wipe(source[i]);
2615     }
2616     else static if (is(T == struct) && hasContextPointers!T)
2617     {
2618         import core.internal.traits : anySatisfy;
2619         static if (anySatisfy!(hasContextPointers, typeof(T.tupleof)))
2620         {
2621             static foreach (i; 0 .. T.tupleof.length - __traits(isNested, T))
2622                 static if (Init.length)
2623                     wipe(source.tupleof[i], initializer[0].tupleof[i]);
2624                 else
2625                     wipe(source.tupleof[i]);
2626         }
2627         else
2628         {
2629             static if (__traits(isNested, T))
2630                 enum sz = T.tupleof[$-1].offsetof;
2631             else
2632                 enum sz = T.sizeof;
2633 
2634             static if (Init.length)
2635                 *cast(ubyte[sz]*) &source = *cast(ubyte[sz]*) &initializer[0];
2636             else
2637                 *cast(ubyte[sz]*) &source = 0;
2638         }
2639     }
2640     else
2641     {
2642         import core.internal.traits : hasElaborateAssign, isAssignable;
2643         static if (Init.length)
2644         {
2645             static if (hasElaborateAssign!T || !isAssignable!T)
2646                 *cast(ubyte[T.sizeof]*) &source = *cast(ubyte[T.sizeof]*) &initializer[0];
2647             else
2648                 source = *cast(T*) &initializer[0];
2649         }
2650         else
2651         {
2652             *cast(ubyte[T.sizeof]*) &source = 0;
2653         }
2654     }
2655 }
2656 
2657 /**
2658  * Allocate an exception of type `T` from the exception pool.
2659  * `T` must be `Throwable` or derived from it and cannot be a COM or C++ class.
2660  *
2661  * Note:
2662  *  This function does not call the constructor of `T` because that would require
2663  *  `forward!args`, which causes errors with -dip1008. This inconvenience will be
2664  *  removed once -dip1008 works as intended.
2665  *
2666  * Returns:
2667  *   allocated instance of type `T`
2668  */
2669 T _d_newThrowable(T)() @trusted
2670     if (is(T : Throwable) && __traits(getLinkage, T) == "D")
2671 {
2672     debug(PRINTF) printf("_d_newThrowable(%s)\n", cast(char*) T.stringof);
2673 
2674     import core.memory : pureMalloc;
2675     auto init = __traits(initSymbol, T);
2676     void* p = pureMalloc(init.length);
2677     if (!p)
2678     {
2679         import core.exception : onOutOfMemoryError;
2680         onOutOfMemoryError();
2681     }
2682 
2683     debug(PRINTF) printf(" p = %p\n", p);
2684 
2685     // initialize it
2686     p[0 .. init.length] = init[];
2687 
2688     import core.internal.traits : hasIndirections;
2689     if (hasIndirections!T)
2690     {
2691         // Inform the GC about the pointers in the object instance
2692         import core.memory : GC;
2693         GC.addRange(p, init.length);
2694     }
2695 
2696     debug(PRINTF) printf("initialization done\n");
2697 
2698     (cast(Throwable) p).refcount() = 1;
2699 
2700     return cast(T) p;
2701 }
2702 
2703 @system unittest
2704 {
2705     class E : Exception
2706     {
2707         this(string msg = "", Throwable nextInChain = null)
2708         {
2709             super(msg, nextInChain);
2710         }
2711     }
2712 
2713     Throwable exc = _d_newThrowable!Exception();
2714     Throwable e = _d_newThrowable!E();
2715 
2716     assert(exc.refcount() == 1);
2717     assert(e.refcount() == 1);
2718 }
2719 
2720 /**
2721  * Create a new class instance.
2722  * Allocates memory and sets fields to their initial value, but does not call a
2723  * constructor.
2724  * ---
2725  * new C() // _d_newclass!(C)()
2726  * ---
2727  * Returns: newly created object
2728  */
2729 T _d_newclassT(T)() @trusted
2730 if (is(T == class))
2731 {
2732     import core.internal.traits : hasIndirections;
2733     import core.exception : onOutOfMemoryError;
2734     import core.memory : pureMalloc;
2735     import core.memory : GC;
2736 
2737     alias BlkAttr = GC.BlkAttr;
2738 
2739     auto init = __traits(initSymbol, T);
2740     void* p;
2741 
2742     static if (__traits(getLinkage, T) == "Windows")
2743     {
2744         p = pureMalloc(init.length);
2745         if (!p)
2746             onOutOfMemoryError();
2747     }
2748     else
2749     {
2750         BlkAttr attr = BlkAttr.NONE;
2751 
2752         /* `extern(C++)`` classes don't have a classinfo pointer in their vtable,
2753          * so the GC can't finalize them.
2754          */
2755         static if (__traits(hasMember, T, "__dtor") && __traits(getLinkage, T) != "C++")
2756             attr |= BlkAttr.FINALIZE;
2757         static if (!hasIndirections!T)
2758             attr |= BlkAttr.NO_SCAN;
2759 
2760         p = GC.malloc(init.length, attr, typeid(T));
2761         debug(PRINTF) printf(" p = %p\n", p);
2762     }
2763 
2764     debug(PRINTF)
2765     {
2766         printf("p = %p\n", p);
2767         printf("init.ptr = %p, len = %llu\n", init.ptr, cast(ulong)init.length);
2768         printf("vptr = %p\n", *cast(void**) init);
2769         printf("vtbl[0] = %p\n", (*cast(void***) init)[0]);
2770         printf("vtbl[1] = %p\n", (*cast(void***) init)[1]);
2771         printf("init[0] = %x\n", (cast(uint*) init)[0]);
2772         printf("init[1] = %x\n", (cast(uint*) init)[1]);
2773         printf("init[2] = %x\n", (cast(uint*) init)[2]);
2774         printf("init[3] = %x\n", (cast(uint*) init)[3]);
2775         printf("init[4] = %x\n", (cast(uint*) init)[4]);
2776     }
2777 
2778     // initialize it
2779     p[0 .. init.length] = init[];
2780 
2781     debug(PRINTF) printf("initialization done\n");
2782     return cast(T) p;
2783 }
2784 
2785 /**
2786  * TraceGC wrapper around $(REF _d_newclassT, core,lifetime).
2787  */
2788 T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted
2789 {
2790     version (D_TypeInfo)
2791     {
2792         import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
2793         mixin(TraceHook!(T.stringof, "_d_newclassT"));
2794 
2795         return _d_newclassT!T();
2796     }
2797     else
2798         assert(0, "Cannot create new class if compiling without support for runtime type information!");
2799 }
2800 
2801 /**
2802  * Allocate an initialized non-array item.
2803  *
2804  * This is an optimization to avoid things needed for arrays like the __arrayPad(size).
2805  * Used to allocate struct instances on the heap.
2806  *
2807  * ---
2808  * struct Sz {int x = 0;}
2809  * struct Si {int x = 3;}
2810  *
2811  * void main()
2812  * {
2813  *     new Sz(); // uses zero-initialization
2814  *     new Si(); // uses Si.init
2815  * }
2816  * ---
2817  *
2818  * Returns:
2819  *     newly allocated item
2820  */
2821 T* _d_newitemT(T)() @trusted
2822 {
2823     import core.internal.lifetime : emplaceInitializer;
2824     import core.internal.traits : hasIndirections;
2825     import core.memory : GC;
2826 
2827     auto flags = !hasIndirections!T ? GC.BlkAttr.NO_SCAN : GC.BlkAttr.NONE;
2828     immutable tiSize = TypeInfoSize!T;
2829     immutable itemSize = T.sizeof;
2830     immutable totalSize = itemSize + tiSize;
2831     if (tiSize)
2832         flags |= GC.BlkAttr.STRUCTFINAL | GC.BlkAttr.FINALIZE;
2833 
2834     auto blkInfo = GC.qalloc(totalSize, flags, null);
2835     auto p = blkInfo.base;
2836 
2837     if (tiSize)
2838     {
2839         // The GC might not have cleared the padding area in the block.
2840         *cast(TypeInfo*) (p + (itemSize & ~(size_t.sizeof - 1))) = null;
2841         *cast(TypeInfo*) (p + blkInfo.size - tiSize) = cast() typeid(T);
2842     }
2843 
2844     emplaceInitializer(*(cast(T*) p));
2845 
2846     return cast(T*) p;
2847 }
2848 
2849 // Test allocation
2850 @safe unittest
2851 {
2852     class C { }
2853     C c = _d_newclassT!C();
2854 
2855     assert(c !is null);
2856 }
2857 
2858 // Test initializers
2859 @safe unittest
2860 {
2861     {
2862         class C { int x, y; }
2863         C c = _d_newclassT!C();
2864 
2865         assert(c.x == 0);
2866         assert(c.y == 0);
2867     }
2868     {
2869         class C { int x = 2, y = 3; }
2870         C c = _d_newclassT!C();
2871 
2872         assert(c.x == 2);
2873         assert(c.y == 3);
2874     }
2875 }
2876 
2877 // Test allocation
2878 @safe unittest
2879 {
2880     struct S { }
2881     S* s = _d_newitemT!S();
2882 
2883     assert(s !is null);
2884 }
2885 
2886 // Test initializers
2887 @safe unittest
2888 {
2889     {
2890         // zero-initialization
2891         struct S { int x, y; }
2892         S* s = _d_newitemT!S();
2893 
2894         assert(s.x == 0);
2895         assert(s.y == 0);
2896     }
2897     {
2898         // S.init
2899         struct S { int x = 2, y = 3; }
2900         S* s = _d_newitemT!S();
2901 
2902         assert(s.x == 2);
2903         assert(s.y == 3);
2904     }
2905 }
2906 
2907 // Test GC attributes
2908 version (CoreUnittest)
2909 {
2910     struct S1
2911     {
2912         int x = 5;
2913     }
2914     struct S2
2915     {
2916         int x;
2917         this(int x) { this.x = x; }
2918     }
2919     struct S3
2920     {
2921         int[4] x;
2922         this(int x) { this.x[] = x; }
2923     }
2924     struct S4
2925     {
2926         int *x;
2927     }
2928 
2929 }
2930 @system unittest
2931 {
2932     import core.memory : GC;
2933 
2934     auto s1 = new S1;
2935     assert(s1.x == 5);
2936     assert(GC.getAttr(s1) == GC.BlkAttr.NO_SCAN);
2937 
2938     auto s2 = new S2(3);
2939     assert(s2.x == 3);
2940     assert(GC.getAttr(s2) == GC.BlkAttr.NO_SCAN);
2941 
2942     auto s3 = new S3(1);
2943     assert(s3.x == [1, 1, 1, 1]);
2944     assert(GC.getAttr(s3) == GC.BlkAttr.NO_SCAN);
2945     debug(SENTINEL) {} else
2946         assert(GC.sizeOf(s3) == 16);
2947 
2948     auto s4 = new S4;
2949     assert(s4.x == null);
2950     assert(GC.getAttr(s4) == 0);
2951 }
2952 
2953 // Test struct finalizers exception handling
2954 debug(SENTINEL) {} else
2955 @system unittest
2956 {
2957     import core.memory : GC;
2958 
2959     bool test(E)()
2960     {
2961         import core.exception;
2962         static struct S1
2963         {
2964             E exc;
2965             ~this() { throw exc; }
2966         }
2967 
2968         bool caught = false;
2969         S1* s = new S1(new E("test onFinalizeError"));
2970         try
2971         {
2972             GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0 .. 1]);
2973         }
2974         catch (FinalizeError err)
2975         {
2976             caught = true;
2977         }
2978         catch (E)
2979         {
2980         }
2981         GC.free(s);
2982         return caught;
2983     }
2984 
2985     assert(test!Exception);
2986     import core.exception : InvalidMemoryOperationError;
2987     assert(!test!InvalidMemoryOperationError);
2988 }
2989 
2990 version (D_ProfileGC)
2991 {
2992     /**
2993     * TraceGC wrapper around $(REF _d_newitemT, core,lifetime).
2994     */
2995     T* _d_newitemTTrace(T)(string file, int line, string funcname) @trusted
2996     {
2997         version (D_TypeInfo)
2998         {
2999             import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
3000             mixin(TraceHook!(T.stringof, "_d_newitemT"));
3001 
3002             return _d_newitemT!T();
3003         }
3004         else
3005             assert(0, "Cannot create new `struct` if compiling without support for runtime type information!");
3006     }
3007 }
3008 
3009 template TypeInfoSize(T)
3010 {
3011     import core.internal.traits : hasElaborateDestructor;
3012     enum TypeInfoSize = (is (T == struct) && hasElaborateDestructor!T) ? size_t.sizeof : 0;
3013 }