"Fossies" - the Fresh Open Source Software Archive

Member "dmd2/src/druntime/src/core/lifetime.d" (20 Nov 2020, 41549 Bytes) of package /linux/misc/dmd.2.094.2.linux.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) D source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 module core.lifetime;
    2 
    3 // emplace
    4 /**
    5 Given a pointer `chunk` to uninitialized memory (but already typed
    6 as `T`), constructs an object of non-`class` type `T` at that
    7 address. If `T` is a class, initializes the class reference to null.
    8 Returns: A pointer to the newly constructed object (which is the same
    9 as `chunk`).
   10  */
   11 T* emplace(T)(T* chunk) @safe pure nothrow
   12 {
   13     import core.internal.lifetime : emplaceRef;
   14 
   15     emplaceRef!T(*chunk);
   16     return chunk;
   17 }
   18 
   19 ///
   20 @system unittest
   21 {
   22     static struct S
   23     {
   24         int i = 42;
   25     }
   26     S[2] s2 = void;
   27     emplace(&s2);
   28     assert(s2[0].i == 42 && s2[1].i == 42);
   29 }
   30 
   31 ///
   32 @system unittest
   33 {
   34     interface I {}
   35     class K : I {}
   36 
   37     K k = void;
   38     emplace(&k);
   39     assert(k is null);
   40 
   41     I i = void;
   42     emplace(&i);
   43     assert(i is null);
   44 }
   45 
   46 /**
   47 Given a pointer `chunk` to uninitialized memory (but already typed
   48 as a non-class type `T`), constructs an object of type `T` at
   49 that address from arguments `args`. If `T` is a class, initializes
   50 the class reference to `args[0]`.
   51 This function can be `@trusted` if the corresponding constructor of
   52 `T` is `@safe`.
   53 Returns: A pointer to the newly constructed object (which is the same
   54 as `chunk`).
   55  */
   56 T* emplace(T, Args...)(T* chunk, auto ref Args args)
   57     if (is(T == struct) || Args.length == 1)
   58 {
   59     import core.internal.lifetime : emplaceRef;
   60 
   61     emplaceRef!T(*chunk, forward!args);
   62     return chunk;
   63 }
   64 
   65 ///
   66 @system unittest
   67 {
   68     int a;
   69     int b = 42;
   70     assert(*emplace!int(&a, b) == 42);
   71 }
   72 
   73 @system unittest
   74 {
   75     shared int i;
   76     emplace(&i, 42);
   77     assert(i == 42);
   78 }
   79 
   80 private @nogc pure nothrow @safe
   81 void testEmplaceChunk(void[] chunk, size_t typeSize, size_t typeAlignment)
   82 {
   83     assert(chunk.length >= typeSize, "emplace: Chunk size too small.");
   84     assert((cast(size_t) chunk.ptr) % typeAlignment == 0, "emplace: Chunk is not aligned.");
   85 }
   86 
   87 /**
   88 Given a raw memory area `chunk` (but already typed as a class type `T`),
   89 constructs an object of `class` type `T` at that address. The constructor
   90 is passed the arguments `Args`.
   91 If `T` is an inner class whose `outer` field can be used to access an instance
   92 of the enclosing class, then `Args` must not be empty, and the first member of it
   93 must be a valid initializer for that `outer` field. Correct initialization of
   94 this field is essential to access members of the outer class inside `T` methods.
   95 Note:
   96 This function is `@safe` if the corresponding constructor of `T` is `@safe`.
   97 Returns: The newly constructed object.
   98  */
   99 T emplace(T, Args...)(T chunk, auto ref Args args)
  100     if (is(T == class))
  101 {
  102     import core.internal.traits : isInnerClass;
  103 
  104     static assert(!__traits(isAbstractClass, T), T.stringof ~
  105         " is abstract and it can't be emplaced");
  106 
  107     // Initialize the object in its pre-ctor state
  108     enum classSize = __traits(classInstanceSize, T);
  109     (() @trusted => (cast(void*) chunk)[0 .. classSize] = typeid(T).initializer[])();
  110 
  111     static if (isInnerClass!T)
  112     {
  113         static assert(Args.length > 0,
  114             "Initializing an inner class requires a pointer to the outer class");
  115         static assert(is(Args[0] : typeof(T.outer)),
  116             "The first argument must be a pointer to the outer class");
  117 
  118         chunk.outer = args[0];
  119         alias args1 = args[1..$];
  120     }
  121     else alias args1 = args;
  122 
  123     // Call the ctor if any
  124     static if (is(typeof(chunk.__ctor(args1))))
  125     {
  126         // T defines a genuine constructor accepting args
  127         // Go the classic route: write .init first, then call ctor
  128         chunk.__ctor(args1);
  129     }
  130     else
  131     {
  132         static assert(args1.length == 0 && !is(typeof(&T.__ctor)),
  133             "Don't know how to initialize an object of type "
  134             ~ T.stringof ~ " with arguments " ~ typeof(args1).stringof);
  135     }
  136     return chunk;
  137 }
  138 
  139 ///
  140 @safe unittest
  141 {
  142     () @safe {
  143         class SafeClass
  144         {
  145             int x;
  146             @safe this(int x) { this.x = x; }
  147         }
  148 
  149         auto buf = new void[__traits(classInstanceSize, SafeClass)];
  150         auto support = (() @trusted => cast(SafeClass)(buf.ptr))();
  151         auto safeClass = emplace!SafeClass(support, 5);
  152         assert(safeClass.x == 5);
  153 
  154         class UnsafeClass
  155         {
  156             int x;
  157             @system this(int x) { this.x = x; }
  158         }
  159 
  160         auto buf2 = new void[__traits(classInstanceSize, UnsafeClass)];
  161         auto support2 = (() @trusted => cast(UnsafeClass)(buf2.ptr))();
  162         static assert(!__traits(compiles, emplace!UnsafeClass(support2, 5)));
  163         static assert(!__traits(compiles, emplace!UnsafeClass(buf2, 5)));
  164     }();
  165 }
  166 
  167 @safe unittest
  168 {
  169     class Outer
  170     {
  171         int i = 3;
  172         class Inner
  173         {
  174             @safe auto getI() { return i; }
  175         }
  176     }
  177     auto outerBuf = new void[__traits(classInstanceSize, Outer)];
  178     auto outerSupport = (() @trusted => cast(Outer)(outerBuf.ptr))();
  179 
  180     auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
  181     auto innerSupport = (() @trusted => cast(Outer.Inner)(innerBuf.ptr))();
  182 
  183     auto inner = innerSupport.emplace!(Outer.Inner)(outerSupport.emplace!Outer);
  184     assert(inner.getI == 3);
  185 }
  186 
  187 /**
  188 Given a raw memory area `chunk`, constructs an object of `class` type `T` at
  189 that address. The constructor is passed the arguments `Args`.
  190 If `T` is an inner class whose `outer` field can be used to access an instance
  191 of the enclosing class, then `Args` must not be empty, and the first member of it
  192 must be a valid initializer for that `outer` field. Correct initialization of
  193 this field is essential to access members of the outer class inside `T` methods.
  194 Preconditions:
  195 `chunk` must be at least as large as `T` needs and should have an alignment
  196 multiple of `T`'s alignment. (The size of a `class` instance is obtained by using
  197 $(D __traits(classInstanceSize, T))).
  198 Note:
  199 This function can be `@trusted` if the corresponding constructor of `T` is `@safe`.
  200 Returns: The newly constructed object.
  201  */
  202 T emplace(T, Args...)(void[] chunk, auto ref Args args)
  203     if (is(T == class))
  204 {
  205     import core.internal.traits : maxAlignment;
  206     enum classSize = __traits(classInstanceSize, T);
  207     testEmplaceChunk(chunk, classSize, maxAlignment!(void*, typeof(T.tupleof)));
  208     return emplace!T(cast(T)(chunk.ptr), args);
  209 }
  210 
  211 ///
  212 @system unittest
  213 {
  214     static class C
  215     {
  216         int i;
  217         this(int i){this.i = i;}
  218     }
  219     auto buf = new void[__traits(classInstanceSize, C)];
  220     auto c = emplace!C(buf, 5);
  221     assert(c.i == 5);
  222 }
  223 
  224 @system unittest
  225 {
  226     class Outer
  227     {
  228         int i = 3;
  229         class Inner
  230         {
  231             auto getI() { return i; }
  232         }
  233     }
  234     auto outerBuf = new void[__traits(classInstanceSize, Outer)];
  235     auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
  236     auto inner = innerBuf.emplace!(Outer.Inner)(outerBuf.emplace!Outer);
  237     assert(inner.getI == 3);
  238 }
  239 
  240 @nogc pure nothrow @safe unittest
  241 {
  242     static class __conv_EmplaceTestClass
  243     {
  244         int i = 3;
  245         this(int i) @nogc @safe pure nothrow
  246         {
  247             assert(this.i == 3 && i == 5);
  248             this.i = i;
  249         }
  250         this(int i, ref int j) @nogc @safe pure nothrow
  251         {
  252             assert(i == 5 && j == 6);
  253             this.i = i;
  254             ++j;
  255         }
  256     }
  257     int var = 6;
  258     align(__conv_EmplaceTestClass.alignof) ubyte[__traits(classInstanceSize, __conv_EmplaceTestClass)] buf;
  259     auto support = (() @trusted => cast(__conv_EmplaceTestClass)(buf.ptr))();
  260     auto k = emplace!__conv_EmplaceTestClass(support, 5, var);
  261     assert(k.i == 5);
  262     assert(var == 7);
  263 }
  264 
  265 /**
  266 Given a raw memory area `chunk`, constructs an object of non-$(D
  267 class) type `T` at that address. The constructor is passed the
  268 arguments `args`, if any.
  269 Preconditions:
  270 `chunk` must be at least as large
  271 as `T` needs and should have an alignment multiple of `T`'s
  272 alignment.
  273 Note:
  274 This function can be `@trusted` if the corresponding constructor of
  275 `T` is `@safe`.
  276 Returns: A pointer to the newly constructed object.
  277  */
  278 T* emplace(T, Args...)(void[] chunk, auto ref Args args)
  279     if (!is(T == class))
  280 {
  281     import core.internal.traits : Unqual;
  282     import core.internal.lifetime : emplaceRef;
  283 
  284     testEmplaceChunk(chunk, T.sizeof, T.alignof);
  285     emplaceRef!(T, Unqual!T)(*cast(Unqual!T*) chunk.ptr, args);
  286     return cast(T*) chunk.ptr;
  287 }
  288 
  289 ///
  290 @system unittest
  291 {
  292     struct S
  293     {
  294         int a, b;
  295     }
  296     auto buf = new void[S.sizeof];
  297     S s;
  298     s.a = 42;
  299     s.b = 43;
  300     auto s1 = emplace!S(buf, s);
  301     assert(s1.a == 42 && s1.b == 43);
  302 }
  303 
  304 // Bulk of emplace unittests starts here
  305 
  306 @system unittest /* unions */
  307 {
  308     static union U
  309     {
  310         string a;
  311         int b;
  312         struct
  313         {
  314             long c;
  315             int[] d;
  316         }
  317     }
  318     U u1 = void;
  319     U u2 = { "hello" };
  320     emplace(&u1, u2);
  321     assert(u1.a == "hello");
  322 }
  323 
  324 @system unittest // bugzilla 15772
  325 {
  326     abstract class Foo {}
  327     class Bar: Foo {}
  328     void[] memory;
  329     // test in emplaceInitializer
  330     static assert(!is(typeof(emplace!Foo(cast(Foo*) memory.ptr))));
  331     static assert( is(typeof(emplace!Bar(cast(Bar*) memory.ptr))));
  332     // test in the emplace overload that takes void[]
  333     static assert(!is(typeof(emplace!Foo(memory))));
  334     static assert( is(typeof(emplace!Bar(memory))));
  335 }
  336 
  337 @system unittest
  338 {
  339     struct S { @disable this(); }
  340     S s = void;
  341     static assert(!__traits(compiles, emplace(&s)));
  342     emplace(&s, S.init);
  343 }
  344 
  345 @system unittest
  346 {
  347     struct S1
  348     {}
  349 
  350     struct S2
  351     {
  352         void opAssign(S2);
  353     }
  354 
  355     S1 s1 = void;
  356     S2 s2 = void;
  357     S1[2] as1 = void;
  358     S2[2] as2 = void;
  359     emplace(&s1);
  360     emplace(&s2);
  361     emplace(&as1);
  362     emplace(&as2);
  363 }
  364 
  365 @system unittest
  366 {
  367     static struct S1
  368     {
  369         this(this) @disable;
  370     }
  371     static struct S2
  372     {
  373         this() @disable;
  374     }
  375     S1[2] ss1 = void;
  376     S2[2] ss2 = void;
  377     emplace(&ss1);
  378     static assert(!__traits(compiles, emplace(&ss2)));
  379     S1 s1 = S1.init;
  380     S2 s2 = S2.init;
  381     static assert(!__traits(compiles, emplace(&ss1, s1)));
  382     emplace(&ss2, s2);
  383 }
  384 
  385 @system unittest
  386 {
  387     struct S
  388     {
  389         immutable int i;
  390     }
  391     S s = void;
  392     S[2] ss1 = void;
  393     S[2] ss2 = void;
  394     emplace(&s, 5);
  395     assert(s.i == 5);
  396     emplace(&ss1, s);
  397     assert(ss1[0].i == 5 && ss1[1].i == 5);
  398     emplace(&ss2, ss1);
  399     assert(ss2 == ss1);
  400 }
  401 
  402 //Start testing emplace-args here
  403 
  404 @system unittest
  405 {
  406     interface I {}
  407     class K : I {}
  408 
  409     K k = null, k2 = new K;
  410     assert(k !is k2);
  411     emplace!K(&k, k2);
  412     assert(k is k2);
  413 
  414     I i = null;
  415     assert(i !is k);
  416     emplace!I(&i, k);
  417     assert(i is k);
  418 }
  419 
  420 @system unittest
  421 {
  422     static struct S
  423     {
  424         int i = 5;
  425         void opAssign(S){assert(0);}
  426     }
  427     S[2] sa = void;
  428     S[2] sb;
  429     emplace(&sa, sb);
  430     assert(sa[0].i == 5 && sa[1].i == 5);
  431 }
  432 
  433 //Start testing emplace-struct here
  434 
  435 // Test constructor branch
  436 @system unittest
  437 {
  438     struct S
  439     {
  440         double x = 5, y = 6;
  441         this(int a, int b)
  442         {
  443             assert(x == 5 && y == 6);
  444             x = a;
  445             y = b;
  446         }
  447     }
  448 
  449     auto s1 = new void[S.sizeof];
  450     auto s2 = S(42, 43);
  451     assert(*emplace!S(cast(S*) s1.ptr, s2) == s2);
  452     assert(*emplace!S(cast(S*) s1, 44, 45) == S(44, 45));
  453 }
  454 
  455 @system unittest
  456 {
  457     static struct __conv_EmplaceTest
  458     {
  459         int i = 3;
  460         this(int i)
  461         {
  462             assert(this.i == 3 && i == 5);
  463             this.i = i;
  464         }
  465         this(int i, ref int j)
  466         {
  467             assert(i == 5 && j == 6);
  468             this.i = i;
  469             ++j;
  470         }
  471 
  472     @disable:
  473         this();
  474         this(this);
  475         void opAssign();
  476     }
  477 
  478     __conv_EmplaceTest k = void;
  479     emplace(&k, 5);
  480     assert(k.i == 5);
  481 
  482     int var = 6;
  483     __conv_EmplaceTest x = void;
  484     emplace(&x, 5, var);
  485     assert(x.i == 5);
  486     assert(var == 7);
  487 
  488     var = 6;
  489     auto z = emplace!__conv_EmplaceTest(new void[__conv_EmplaceTest.sizeof], 5, var);
  490     assert(z.i == 5);
  491     assert(var == 7);
  492 }
  493 
  494 // Test matching fields branch
  495 @system unittest
  496 {
  497     struct S { uint n; }
  498     S s;
  499     emplace!S(&s, 2U);
  500     assert(s.n == 2);
  501 }
  502 
  503 @safe unittest
  504 {
  505     struct S { int a, b; this(int){} }
  506     S s;
  507     static assert(!__traits(compiles, emplace!S(&s, 2, 3)));
  508 }
  509 
  510 @system unittest
  511 {
  512     struct S { int a, b = 7; }
  513     S s1 = void, s2 = void;
  514 
  515     emplace!S(&s1, 2);
  516     assert(s1.a == 2 && s1.b == 7);
  517 
  518     emplace!S(&s2, 2, 3);
  519     assert(s2.a == 2 && s2.b == 3);
  520 }
  521 
  522 //opAssign
  523 @system unittest
  524 {
  525     static struct S
  526     {
  527         int i = 5;
  528         void opAssign(int){assert(0);}
  529         void opAssign(S){assert(0);}
  530     }
  531     S sa1 = void;
  532     S sa2 = void;
  533     S sb1 = S(1);
  534     emplace(&sa1, sb1);
  535     emplace(&sa2, 2);
  536     assert(sa1.i == 1);
  537     assert(sa2.i == 2);
  538 }
  539 
  540 //postblit precedence
  541 @system unittest
  542 {
  543     //Works, but breaks in "-w -O" because of @@@9332@@@.
  544     //Uncomment test when 9332 is fixed.
  545     static struct S
  546     {
  547         int i;
  548 
  549         this(S other){assert(false);}
  550         this(int i){this.i = i;}
  551         this(this){}
  552     }
  553     S a = void;
  554     assert(is(typeof({S b = a;})));    //Postblit
  555     assert(is(typeof({S b = S(a);}))); //Constructor
  556     auto b = S(5);
  557     emplace(&a, b);
  558     assert(a.i == 5);
  559 
  560     static struct S2
  561     {
  562         int* p;
  563         this(const S2){}
  564     }
  565     static assert(!is(immutable S2 : S2));
  566     S2 s2 = void;
  567     immutable is2 = (immutable S2).init;
  568     emplace(&s2, is2);
  569 }
  570 
  571 //nested structs and postblit
  572 @system unittest
  573 {
  574     static struct S
  575     {
  576         int* p;
  577         this(int i){p = [i].ptr;}
  578         this(this)
  579         {
  580             if (p)
  581                 p = [*p].ptr;
  582         }
  583     }
  584     static struct SS
  585     {
  586         S s;
  587         void opAssign(const SS)
  588         {
  589             assert(0);
  590         }
  591     }
  592     SS ssa = void;
  593     SS ssb = SS(S(5));
  594     emplace(&ssa, ssb);
  595     assert(*ssa.s.p == 5);
  596     assert(ssa.s.p != ssb.s.p);
  597 }
  598 
  599 //disabled postblit
  600 @system unittest
  601 {
  602     static struct S1
  603     {
  604         int i;
  605         @disable this(this);
  606     }
  607     S1 s1 = void;
  608     emplace(&s1, 1);
  609     assert(s1.i == 1);
  610     static assert(!__traits(compiles, emplace(&s1, s1))); // copy disabled
  611     static assert(__traits(compiles, emplace(&s1, move(s1)))); // move not affected
  612 
  613     static struct S2
  614     {
  615         int i;
  616         @disable this(this);
  617         this(ref S2){}
  618     }
  619     S2 s2 = void;
  620     static assert(!__traits(compiles, emplace(&s2, 1)));
  621     emplace(&s2, S2.init);
  622 
  623     static struct SS1
  624     {
  625         S1 s;
  626     }
  627     SS1 ss1 = void;
  628     emplace(&ss1);
  629     static assert(!__traits(compiles, emplace(&ss1, ss1))); // copying disabled
  630     static assert(__traits(compiles, emplace(&ss1, move(ss1)))); // move unaffected
  631 
  632     static struct SS2
  633     {
  634         S2 s;
  635     }
  636     SS2 ss2 = void;
  637     emplace(&ss2);
  638     static assert(!__traits(compiles, emplace(&ss2, ss2))); // copying disabled
  639     static assert(__traits(compiles, emplace(&ss2, SS2.init))); // move is OK
  640 
  641 
  642     // SS1 sss1 = s1;      //This doesn't compile
  643     // SS1 sss1 = SS1(s1); //This doesn't compile
  644     // So emplace shouldn't compile either
  645     static assert(!__traits(compiles, emplace(&sss1, s1)));
  646     static assert(!__traits(compiles, emplace(&sss2, s2)));
  647 }
  648 
  649 //Imutability
  650 @system unittest
  651 {
  652     //Castable immutability
  653     {
  654         static struct S1
  655         {
  656             int i;
  657         }
  658         static assert(is( immutable(S1) : S1));
  659         S1 sa = void;
  660         auto sb = immutable(S1)(5);
  661         emplace(&sa, sb);
  662         assert(sa.i == 5);
  663     }
  664     //Un-castable immutability
  665     {
  666         static struct S2
  667         {
  668             int* p;
  669         }
  670         static assert(!is(immutable(S2) : S2));
  671         S2 sa = void;
  672         auto sb = immutable(S2)(null);
  673         assert(!__traits(compiles, emplace(&sa, sb)));
  674     }
  675 }
  676 
  677 @system unittest
  678 {
  679     static struct S
  680     {
  681         immutable int i;
  682         immutable(int)* j;
  683     }
  684     S s = void;
  685     emplace(&s, 1, null);
  686     emplace(&s, 2, &s.i);
  687     assert(s is S(2, &s.i));
  688 }
  689 
  690 //Context pointer
  691 @system unittest
  692 {
  693     int i = 0;
  694     {
  695         struct S1
  696         {
  697             void foo(){++i;}
  698         }
  699         S1 sa = void;
  700         S1 sb;
  701         emplace(&sa, sb);
  702         sa.foo();
  703         assert(i == 1);
  704     }
  705     {
  706         struct S2
  707         {
  708             void foo(){++i;}
  709             this(this){}
  710         }
  711         S2 sa = void;
  712         S2 sb;
  713         emplace(&sa, sb);
  714         sa.foo();
  715         assert(i == 2);
  716     }
  717 }
  718 
  719 //Alias this
  720 @system unittest
  721 {
  722     static struct S
  723     {
  724         int i;
  725     }
  726     //By Ref
  727     {
  728         static struct SS1
  729         {
  730             int j;
  731             S s;
  732             alias s this;
  733         }
  734         S s = void;
  735         SS1 ss = SS1(1, S(2));
  736         emplace(&s, ss);
  737         assert(s.i == 2);
  738     }
  739     //By Value
  740     {
  741         static struct SS2
  742         {
  743             int j;
  744             S s;
  745             S foo() @property{return s;}
  746             alias foo this;
  747         }
  748         S s = void;
  749         SS2 ss = SS2(1, S(2));
  750         emplace(&s, ss);
  751         assert(s.i == 2);
  752     }
  753 }
  754 
  755 version (CoreUnittest)
  756 {
  757     //Ambiguity
  758     private struct __std_conv_S
  759     {
  760         int i;
  761         this(__std_conv_SS ss)         {assert(0);}
  762         static opCall(__std_conv_SS ss)
  763         {
  764             __std_conv_S s; s.i = ss.j;
  765             return s;
  766         }
  767     }
  768     private struct __std_conv_SS
  769     {
  770         int j;
  771         __std_conv_S s;
  772         ref __std_conv_S foo() return @property {s.i = j; return s;}
  773         alias foo this;
  774     }
  775 }
  776 
  777 @system unittest
  778 {
  779     static assert(is(__std_conv_SS : __std_conv_S));
  780     __std_conv_S s = void;
  781     __std_conv_SS ss = __std_conv_SS(1);
  782 
  783     __std_conv_S sTest1 = ss; //this calls "SS alias this" (and not "S.this(SS)")
  784     emplace(&s, ss); //"alias this" should take precedence in emplace over "opCall"
  785     assert(s.i == 1);
  786 }
  787 
  788 //Nested classes
  789 @system unittest
  790 {
  791     class A{}
  792     static struct S
  793     {
  794         A a;
  795     }
  796     S s1 = void;
  797     S s2 = S(new A);
  798     emplace(&s1, s2);
  799     assert(s1.a is s2.a);
  800 }
  801 
  802 //safety & nothrow & CTFE
  803 @system unittest
  804 {
  805     //emplace should be safe for anything with no elaborate opassign
  806     static struct S1
  807     {
  808         int i;
  809     }
  810     static struct S2
  811     {
  812         int i;
  813         this(int j)@safe nothrow{i = j;}
  814     }
  815 
  816     int i;
  817     S1 s1 = void;
  818     S2 s2 = void;
  819 
  820     auto pi = &i;
  821     auto ps1 = &s1;
  822     auto ps2 = &s2;
  823 
  824     void foo() @safe nothrow
  825     {
  826         emplace(pi);
  827         emplace(pi, 5);
  828         emplace(ps1);
  829         emplace(ps1, 5);
  830         emplace(ps1, S1.init);
  831         emplace(ps2);
  832         emplace(ps2, 5);
  833         emplace(ps2, S2.init);
  834     }
  835     foo();
  836 
  837     T bar(T)() @property
  838     {
  839         T t/+ = void+/; //CTFE void illegal
  840         emplace(&t, 5);
  841         return t;
  842     }
  843     // CTFE
  844     enum a = bar!int;
  845     static assert(a == 5);
  846     enum b = bar!S1;
  847     static assert(b.i == 5);
  848     enum c = bar!S2;
  849     static assert(c.i == 5);
  850     // runtime
  851     auto aa = bar!int;
  852     assert(aa == 5);
  853     auto bb = bar!S1;
  854     assert(bb.i == 5);
  855     auto cc = bar!S2;
  856     assert(cc.i == 5);
  857 }
  858 
  859 
  860 @system unittest
  861 {
  862     struct S
  863     {
  864         int[2] get(){return [1, 2];}
  865         alias get this;
  866     }
  867     struct SS
  868     {
  869         int[2] ii;
  870     }
  871     struct ISS
  872     {
  873         int[2] ii;
  874     }
  875     S s;
  876     SS ss = void;
  877     ISS iss = void;
  878     emplace(&ss, s);
  879     emplace(&iss, s);
  880     assert(ss.ii == [1, 2]);
  881     assert(iss.ii == [1, 2]);
  882 }
  883 
  884 //disable opAssign
  885 @system unittest
  886 {
  887     static struct S
  888     {
  889         @disable void opAssign(S);
  890     }
  891     S s;
  892     emplace(&s, S.init);
  893 }
  894 
  895 //opCall
  896 @system unittest
  897 {
  898     int i;
  899     //Without constructor
  900     {
  901         static struct S1
  902         {
  903             int i;
  904             static S1 opCall(int*){assert(0);}
  905         }
  906         S1 s = void;
  907         static assert(!__traits(compiles, emplace(&s,  1)));
  908     }
  909     //With constructor
  910     {
  911         static struct S2
  912         {
  913             int i = 0;
  914             static S2 opCall(int*){assert(0);}
  915             static S2 opCall(int){assert(0);}
  916             this(int i){this.i = i;}
  917         }
  918         S2 s = void;
  919         emplace(&s,  1);
  920         assert(s.i == 1);
  921     }
  922     //With postblit ambiguity
  923     {
  924         static struct S3
  925         {
  926             int i = 0;
  927             static S3 opCall(ref S3){assert(0);}
  928         }
  929         S3 s = void;
  930         emplace(&s, S3.init);
  931     }
  932 }
  933 
  934 /+ these tests can't be performed in druntime, but a mirror still exists in phobos...
  935 @safe unittest //@@@9559@@@
  936 {
  937     import std.algorithm.iteration : map;
  938     import std.array : array;
  939     import std.typecons : Nullable;
  940     alias I = Nullable!int;
  941     auto ints = [0, 1, 2].map!(i => i & 1 ? I.init : I(i))();
  942     auto asArray = array(ints);
  943 }
  944 @system unittest //http://forum.dlang.org/post/nxbdgtdlmwscocbiypjs@forum.dlang.org
  945 {
  946     import std.array : array;
  947     import std.datetime : SysTime, UTC;
  948     import std.math : isNaN;
  949     static struct A
  950     {
  951         double i;
  952     }
  953     static struct B
  954     {
  955         invariant()
  956         {
  957             if (j == 0)
  958                 assert(a.i.isNaN(), "why is 'j' zero?? and i is not NaN?");
  959             else
  960                 assert(!a.i.isNaN());
  961         }
  962         SysTime when; // comment this line avoid the breakage
  963         int j;
  964         A a;
  965     }
  966     B b1 = B.init;
  967     assert(&b1); // verify that default eyes invariants are ok;
  968     auto b2 = B(SysTime(0, UTC()), 1, A(1));
  969     assert(&b2);
  970     auto b3 = B(SysTime(0, UTC()), 1, A(1));
  971     assert(&b3);
  972     auto arr = [b2, b3];
  973     assert(arr[0].j == 1);
  974     assert(arr[1].j == 1);
  975     auto a2 = arr.array(); // << bang, invariant is raised, also if b2 and b3 are good
  976 }
  977 +/
  978 
  979 //static arrays
  980 @system unittest
  981 {
  982     static struct S
  983     {
  984         int[2] ii;
  985     }
  986     static struct IS
  987     {
  988         immutable int[2] ii;
  989     }
  990     int[2] ii;
  991     S  s   = void;
  992     IS ims = void;
  993     ubyte ub = 2;
  994     emplace(&s, ub);
  995     emplace(&s, ii);
  996     emplace(&ims, ub);
  997     emplace(&ims, ii);
  998     uint[2] uu;
  999     static assert(!__traits(compiles, {S ss = S(uu);}));
 1000     static assert(!__traits(compiles, emplace(&s, uu)));
 1001 }
 1002 
 1003 @system unittest
 1004 {
 1005     int[2]  sii;
 1006     int[2]  sii2;
 1007     uint[2] uii;
 1008     uint[2] uii2;
 1009     emplace(&sii, 1);
 1010     emplace(&sii, 1U);
 1011     emplace(&uii, 1);
 1012     emplace(&uii, 1U);
 1013     emplace(&sii, sii2);
 1014     //emplace(&sii, uii2); //Sorry, this implementation doesn't know how to...
 1015     //emplace(&uii, sii2); //Sorry, this implementation doesn't know how to...
 1016     emplace(&uii, uii2);
 1017     emplace(&sii, sii2[]);
 1018     //emplace(&sii, uii2[]); //Sorry, this implementation doesn't know how to...
 1019     //emplace(&uii, sii2[]); //Sorry, this implementation doesn't know how to...
 1020     emplace(&uii, uii2[]);
 1021 }
 1022 
 1023 @system unittest
 1024 {
 1025     bool allowDestruction = false;
 1026     struct S
 1027     {
 1028         int i;
 1029         this(this){}
 1030         ~this(){assert(allowDestruction);}
 1031     }
 1032     S s = S(1);
 1033     S[2] ss1 = void;
 1034     S[2] ss2 = void;
 1035     S[2] ss3 = void;
 1036     emplace(&ss1, s);
 1037     emplace(&ss2, ss1);
 1038     emplace(&ss3, ss2[]);
 1039     assert(ss1[1] == s);
 1040     assert(ss2[1] == s);
 1041     assert(ss3[1] == s);
 1042     allowDestruction = true;
 1043 }
 1044 
 1045 @system unittest
 1046 {
 1047     //Checks postblit, construction, and context pointer
 1048     int count = 0;
 1049     struct S
 1050     {
 1051         this(this)
 1052         {
 1053             ++count;
 1054         }
 1055         ~this()
 1056         {
 1057             --count;
 1058         }
 1059     }
 1060 
 1061     S s;
 1062     {
 1063         S[4] ss = void;
 1064         emplace(&ss, s);
 1065         assert(count == 4);
 1066     }
 1067     assert(count == 0);
 1068 }
 1069 
 1070 @system unittest
 1071 {
 1072     struct S
 1073     {
 1074         int i;
 1075     }
 1076     S s;
 1077     S[2][2][2] sss = void;
 1078     emplace(&sss, s);
 1079 }
 1080 
 1081 @system unittest //Constness
 1082 {
 1083     import core.internal.lifetime : emplaceRef;
 1084 
 1085     int a = void;
 1086     emplaceRef!(const int)(a, 5);
 1087 
 1088     immutable i = 5;
 1089     const(int)* p = void;
 1090     emplaceRef!(const int*)(p, &i);
 1091 
 1092     struct S
 1093     {
 1094         int* p;
 1095     }
 1096     alias IS = immutable(S);
 1097     S s = void;
 1098     emplaceRef!IS(s, IS());
 1099     S[2] ss = void;
 1100     emplaceRef!(IS[2])(ss, IS());
 1101 
 1102     IS[2] iss = IS.init;
 1103     emplaceRef!(IS[2])(ss, iss);
 1104     emplaceRef!(IS[2])(ss, iss[]);
 1105 }
 1106 
 1107 pure nothrow @safe @nogc unittest
 1108 {
 1109     import core.internal.lifetime : emplaceRef;
 1110 
 1111     int i;
 1112     emplaceRef(i);
 1113     emplaceRef!int(i);
 1114     emplaceRef(i, 5);
 1115     emplaceRef!int(i, 5);
 1116 }
 1117 
 1118 // Test attribute propagation for UDTs
 1119 pure nothrow @safe /* @nogc */ unittest
 1120 {
 1121     import core.internal.lifetime : emplaceRef;
 1122 
 1123     static struct Safe
 1124     {
 1125         this(this) pure nothrow @safe @nogc {}
 1126     }
 1127 
 1128     Safe safe = void;
 1129     emplaceRef(safe, Safe());
 1130 
 1131     Safe[1] safeArr = [Safe()];
 1132     Safe[1] uninitializedSafeArr = void;
 1133     emplaceRef(uninitializedSafeArr, safe);
 1134     emplaceRef(uninitializedSafeArr, safeArr);
 1135 
 1136     static struct Unsafe
 1137     {
 1138         this(this) @system {}
 1139     }
 1140 
 1141     Unsafe unsafe = void;
 1142     static assert(!__traits(compiles, emplaceRef(unsafe, unsafe)));
 1143 
 1144     Unsafe[1] unsafeArr = [Unsafe()];
 1145     Unsafe[1] uninitializedUnsafeArr = void;
 1146     static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafe)));
 1147     static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafeArr)));
 1148 }
 1149 
 1150 @system unittest
 1151 {
 1152     // Issue 15313
 1153     static struct Node
 1154     {
 1155         int payload;
 1156         Node* next;
 1157         uint refs;
 1158     }
 1159 
 1160     import core.stdc.stdlib : malloc;
 1161     void[] buf = malloc(Node.sizeof)[0 .. Node.sizeof];
 1162 
 1163     const Node* n = emplace!(const Node)(buf, 42, null, 10);
 1164     assert(n.payload == 42);
 1165     assert(n.next == null);
 1166     assert(n.refs == 10);
 1167 }
 1168 
 1169 @system unittest
 1170 {
 1171     class A
 1172     {
 1173         int x = 5;
 1174         int y = 42;
 1175         this(int z)
 1176         {
 1177             assert(x == 5 && y == 42);
 1178             x = y = z;
 1179         }
 1180     }
 1181     void[] buf;
 1182 
 1183     static align(A.alignof) byte[__traits(classInstanceSize, A)] sbuf;
 1184     buf = sbuf[];
 1185     auto a = emplace!A(buf, 55);
 1186     assert(a.x == 55 && a.y == 55);
 1187 
 1188     // emplace in bigger buffer
 1189     buf = new byte[](__traits(classInstanceSize, A) + 10);
 1190     a = emplace!A(buf, 55);
 1191     assert(a.x == 55 && a.y == 55);
 1192 
 1193     // need ctor args
 1194     static assert(!is(typeof(emplace!A(buf))));
 1195 }
 1196 
 1197 //constructor arguments forwarding
 1198 @system unittest
 1199 {
 1200     static struct S
 1201     {
 1202         this()(auto ref long arg)
 1203         {
 1204             // assert that arg is an lvalue
 1205             static assert(__traits(isRef, arg));
 1206         }
 1207         this()(auto ref double arg)
 1208             // assert that arg is an rvalue
 1209         {
 1210             static assert(!__traits(isRef, arg));
 1211         }
 1212     }
 1213     S obj = void;
 1214     long i;
 1215     emplace(&obj, i);   // lvalue
 1216     emplace(&obj, 0.0); // rvalue
 1217 }
 1218 // Bulk of emplace unittests ends here
 1219 
 1220 /**
 1221 Forwards function arguments while keeping `out`, `ref`, and `lazy` on
 1222 the parameters.
 1223 
 1224 Params:
 1225     args = a parameter list or an $(REF AliasSeq,std,meta).
 1226 Returns:
 1227     An `AliasSeq` of `args` with `out`, `ref`, and `lazy` saved.
 1228 */
 1229 template forward(args...)
 1230 {
 1231     import core.internal.traits : AliasSeq;
 1232 
 1233     static if (args.length)
 1234     {
 1235         alias arg = args[0];
 1236         // by ref || lazy || const/immutable
 1237         static if (__traits(isRef,  arg) ||
 1238                    __traits(isOut,  arg) ||
 1239                    __traits(isLazy, arg) ||
 1240                    !is(typeof(move(arg))))
 1241             alias fwd = arg;
 1242         // (r)value
 1243         else
 1244             @property auto fwd(){ return move(arg); }
 1245 
 1246         static if (args.length == 1)
 1247             alias forward = fwd;
 1248         else
 1249             alias forward = AliasSeq!(fwd, forward!(args[1..$]));
 1250     }
 1251     else
 1252         alias forward = AliasSeq!();
 1253 }
 1254 
 1255 ///
 1256 @safe unittest
 1257 {
 1258     class C
 1259     {
 1260         static int foo(int n) { return 1; }
 1261         static int foo(ref int n) { return 2; }
 1262     }
 1263 
 1264     // with forward
 1265     int bar()(auto ref int x) { return C.foo(forward!x); }
 1266 
 1267     // without forward
 1268     int baz()(auto ref int x) { return C.foo(x); }
 1269 
 1270     int i;
 1271     assert(bar(1) == 1);
 1272     assert(bar(i) == 2);
 1273 
 1274     assert(baz(1) == 2);
 1275     assert(baz(i) == 2);
 1276 }
 1277 
 1278 ///
 1279 @safe unittest
 1280 {
 1281     void foo(int n, ref string s) { s = null; foreach (i; 0 .. n) s ~= "Hello"; }
 1282 
 1283     // forwards all arguments which are bound to parameter tuple
 1284     void bar(Args...)(auto ref Args args) { return foo(forward!args); }
 1285 
 1286     // forwards all arguments with swapping order
 1287     void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }
 1288 
 1289     string s;
 1290     bar(1, s);
 1291     assert(s == "Hello");
 1292     baz(s, 2);
 1293     assert(s == "HelloHello");
 1294 }
 1295 
 1296 @safe unittest
 1297 {
 1298     auto foo(TL...)(auto ref TL args)
 1299     {
 1300         string result = "";
 1301         foreach (i, _; args)
 1302         {
 1303             //pragma(msg, "[",i,"] ", __traits(isRef, args[i]) ? "L" : "R");
 1304             result ~= __traits(isRef, args[i]) ? "L" : "R";
 1305         }
 1306         return result;
 1307     }
 1308 
 1309     string bar(TL...)(auto ref TL args)
 1310     {
 1311         return foo(forward!args);
 1312     }
 1313     string baz(TL...)(auto ref TL args)
 1314     {
 1315         int x;
 1316         return foo(forward!args[3], forward!args[2], 1, forward!args[1], forward!args[0], x);
 1317     }
 1318 
 1319     struct S {}
 1320     S makeS(){ return S(); }
 1321     int n;
 1322     string s;
 1323     assert(bar(S(), makeS(), n, s) == "RRLL");
 1324     assert(baz(S(), makeS(), n, s) == "LLRRRL");
 1325 }
 1326 
 1327 @safe unittest
 1328 {
 1329     ref int foo(return ref int a) { return a; }
 1330     ref int bar(Args)(auto ref Args args)
 1331     {
 1332         return foo(forward!args);
 1333     }
 1334     static assert(!__traits(compiles, { auto x1 = bar(3); })); // case of NG
 1335     int value = 3;
 1336     auto x2 = bar(value); // case of OK
 1337 }
 1338 
 1339 ///
 1340 @safe unittest
 1341 {
 1342     struct X {
 1343         int i;
 1344         this(this)
 1345         {
 1346             ++i;
 1347         }
 1348     }
 1349 
 1350     struct Y
 1351     {
 1352         private X x_;
 1353         this()(auto ref X x)
 1354         {
 1355             x_ = forward!x;
 1356         }
 1357     }
 1358 
 1359     struct Z
 1360     {
 1361         private const X x_;
 1362         this()(auto ref X x)
 1363         {
 1364             x_ = forward!x;
 1365         }
 1366         this()(auto const ref X x)
 1367         {
 1368             x_ = forward!x;
 1369         }
 1370     }
 1371 
 1372     X x;
 1373     const X cx;
 1374     auto constX = (){ const X x; return x; };
 1375     static assert(__traits(compiles, { Y y = x; }));
 1376     static assert(__traits(compiles, { Y y = X(); }));
 1377     static assert(!__traits(compiles, { Y y = cx; }));
 1378     static assert(!__traits(compiles, { Y y = constX(); }));
 1379     static assert(__traits(compiles, { Z z = x; }));
 1380     static assert(__traits(compiles, { Z z = X(); }));
 1381     static assert(__traits(compiles, { Z z = cx; }));
 1382     static assert(__traits(compiles, { Z z = constX(); }));
 1383 
 1384 
 1385     Y y1 = x;
 1386     // ref lvalue, copy
 1387     assert(y1.x_.i == 1);
 1388     Y y2 = X();
 1389     // rvalue, move
 1390     assert(y2.x_.i == 0);
 1391 
 1392     Z z1 = x;
 1393     // ref lvalue, copy
 1394     assert(z1.x_.i == 1);
 1395     Z z2 = X();
 1396     // rvalue, move
 1397     assert(z2.x_.i == 0);
 1398     Z z3 = cx;
 1399     // ref const lvalue, copy
 1400     assert(z3.x_.i == 1);
 1401     Z z4 = constX();
 1402     // const rvalue, copy
 1403     assert(z4.x_.i == 1);
 1404 }
 1405 
 1406 // lazy -> lazy
 1407 @safe unittest
 1408 {
 1409     int foo1(lazy int i) { return i; }
 1410     int foo2(A)(auto ref A i) { return foo1(forward!i); }
 1411     int foo3(lazy int i) { return foo2(i); }
 1412 
 1413     int numCalls = 0;
 1414     assert(foo3({ ++numCalls; return 42; }()) == 42);
 1415     assert(numCalls == 1);
 1416 }
 1417 
 1418 // lazy -> non-lazy
 1419 @safe unittest
 1420 {
 1421     int foo1(int a, int b) { return a + b; }
 1422     int foo2(A...)(auto ref A args) { return foo1(forward!args); }
 1423     int foo3(int a, lazy int b) { return foo2(a, b); }
 1424 
 1425     int numCalls;
 1426     assert(foo3(11, { ++numCalls; return 31; }()) == 42);
 1427     assert(numCalls == 1);
 1428 }
 1429 
 1430 // non-lazy -> lazy
 1431 @safe unittest
 1432 {
 1433     int foo1(int a, lazy int b) { return a + b; }
 1434     int foo2(A...)(auto ref A args) { return foo1(forward!args); }
 1435     int foo3(int a, int b) { return foo2(a, b); }
 1436 
 1437     assert(foo3(11, 31) == 42);
 1438 }
 1439 
 1440 // out
 1441 @safe unittest
 1442 {
 1443     void foo1(int a, out int b) { b = a; }
 1444     void foo2(A...)(auto ref A args) { foo1(forward!args); }
 1445     void foo3(int a, out int b) { foo2(a, b); }
 1446 
 1447     int b;
 1448     foo3(42, b);
 1449     assert(b == 42);
 1450 }
 1451 
 1452 // move
 1453 /**
 1454 Moves `source` into `target`, via a destructive copy when necessary.
 1455 
 1456 If `T` is a struct with a destructor or postblit defined, source is reset
 1457 to its `.init` value after it is moved into target, otherwise it is
 1458 left unchanged.
 1459 
 1460 Preconditions:
 1461 If source has internal pointers that point to itself, it cannot be moved, and
 1462 will trigger an assertion failure.
 1463 
 1464 Params:
 1465     source = Data to copy.
 1466     target = Where to copy into. The destructor, if any, is invoked before the
 1467         copy is performed.
 1468 */
 1469 void move(T)(ref T source, ref T target)
 1470 {
 1471     // test @safe destructible
 1472     static if (__traits(compiles, (T t) @safe {}))
 1473         trustedMoveImpl(source, target);
 1474     else
 1475         moveImpl(source, target);
 1476 }
 1477 
 1478 /// For non-struct types, `move` just performs `target = source`:
 1479 @safe unittest
 1480 {
 1481     Object obj1 = new Object;
 1482     Object obj2 = obj1;
 1483     Object obj3;
 1484 
 1485     move(obj2, obj3);
 1486     assert(obj3 is obj1);
 1487     // obj2 unchanged
 1488     assert(obj2 is obj1);
 1489 }
 1490 
 1491 ///
 1492 pure nothrow @safe @nogc unittest
 1493 {
 1494     // Structs without destructors are simply copied
 1495     struct S1
 1496     {
 1497         int a = 1;
 1498         int b = 2;
 1499     }
 1500     S1 s11 = { 10, 11 };
 1501     S1 s12;
 1502 
 1503     move(s11, s12);
 1504 
 1505     assert(s12 == S1(10, 11));
 1506     assert(s11 == s12);
 1507 
 1508     // But structs with destructors or postblits are reset to their .init value
 1509     // after copying to the target.
 1510     struct S2
 1511     {
 1512         int a = 1;
 1513         int b = 2;
 1514 
 1515         ~this() pure nothrow @safe @nogc { }
 1516     }
 1517     S2 s21 = { 3, 4 };
 1518     S2 s22;
 1519 
 1520     move(s21, s22);
 1521 
 1522     assert(s21 == S2(1, 2));
 1523     assert(s22 == S2(3, 4));
 1524 }
 1525 
 1526 @safe unittest
 1527 {
 1528     import core.internal.traits;
 1529 
 1530     assertCTFEable!((){
 1531         Object obj1 = new Object;
 1532         Object obj2 = obj1;
 1533         Object obj3;
 1534         move(obj2, obj3);
 1535         assert(obj3 is obj1);
 1536 
 1537         static struct S1 { int a = 1, b = 2; }
 1538         S1 s11 = { 10, 11 };
 1539         S1 s12;
 1540         move(s11, s12);
 1541         assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
 1542 
 1543         static struct S2 { int a = 1; int * b; }
 1544         S2 s21 = { 10, null };
 1545         s21.b = new int;
 1546         S2 s22;
 1547         move(s21, s22);
 1548         assert(s21 == s22);
 1549     });
 1550     // Issue 5661 test(1)
 1551     static struct S3
 1552     {
 1553         static struct X { int n = 0; ~this(){n = 0;} }
 1554         X x;
 1555     }
 1556     static assert(hasElaborateDestructor!S3);
 1557     S3 s31, s32;
 1558     s31.x.n = 1;
 1559     move(s31, s32);
 1560     assert(s31.x.n == 0);
 1561     assert(s32.x.n == 1);
 1562 
 1563     // Issue 5661 test(2)
 1564     static struct S4
 1565     {
 1566         static struct X { int n = 0; this(this){n = 0;} }
 1567         X x;
 1568     }
 1569     static assert(hasElaborateCopyConstructor!S4);
 1570     S4 s41, s42;
 1571     s41.x.n = 1;
 1572     move(s41, s42);
 1573     assert(s41.x.n == 0);
 1574     assert(s42.x.n == 1);
 1575 
 1576     // Issue 13990 test
 1577     class S5;
 1578 
 1579     S5 s51;
 1580     S5 s52 = s51;
 1581     S5 s53;
 1582     move(s52, s53);
 1583     assert(s53 is s51);
 1584 }
 1585 
 1586 /// Ditto
 1587 T move(T)(return scope ref T source)
 1588 {
 1589     // test @safe destructible
 1590     static if (__traits(compiles, (T t) @safe {}))
 1591         return trustedMoveImpl(source);
 1592     else
 1593         return moveImpl(source);
 1594 }
 1595 
 1596 /// Non-copyable structs can still be moved:
 1597 pure nothrow @safe @nogc unittest
 1598 {
 1599     struct S
 1600     {
 1601         int a = 1;
 1602         @disable this(this);
 1603         ~this() pure nothrow @safe @nogc {}
 1604     }
 1605     S s1;
 1606     s1.a = 2;
 1607     S s2 = move(s1);
 1608     assert(s1.a == 1);
 1609     assert(s2.a == 2);
 1610 }
 1611 
 1612 private void trustedMoveImpl(T)(ref T source, ref T target) @trusted
 1613 {
 1614     moveImpl(source, target);
 1615 }
 1616 
 1617 private void moveImpl(T)(ref T source, ref T target)
 1618 {
 1619     import core.internal.traits : hasElaborateDestructor;
 1620 
 1621     static if (is(T == struct))
 1622     {
 1623         if (&source == &target) return;
 1624         // Destroy target before overwriting it
 1625         static if (hasElaborateDestructor!T) target.__xdtor();
 1626     }
 1627     // move and emplace source into target
 1628     moveEmplace(source, target);
 1629 }
 1630 
 1631 private T trustedMoveImpl(T)(ref T source) @trusted
 1632 {
 1633     return moveImpl(source);
 1634 }
 1635 
 1636 private T moveImpl(T)(ref T source)
 1637 {
 1638     T result = void;
 1639     moveEmplace(source, result);
 1640     return result;
 1641 }
 1642 
 1643 @safe unittest
 1644 {
 1645     import core.internal.traits;
 1646 
 1647     assertCTFEable!((){
 1648         Object obj1 = new Object;
 1649         Object obj2 = obj1;
 1650         Object obj3 = move(obj2);
 1651         assert(obj3 is obj1);
 1652 
 1653         static struct S1 { int a = 1, b = 2; }
 1654         S1 s11 = { 10, 11 };
 1655         S1 s12 = move(s11);
 1656         assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
 1657 
 1658         static struct S2 { int a = 1; int * b; }
 1659         S2 s21 = { 10, null };
 1660         s21.b = new int;
 1661         S2 s22 = move(s21);
 1662         assert(s21 == s22);
 1663     });
 1664 
 1665     // Issue 5661 test(1)
 1666     static struct S3
 1667     {
 1668         static struct X { int n = 0; ~this(){n = 0;} }
 1669         X x;
 1670     }
 1671     static assert(hasElaborateDestructor!S3);
 1672     S3 s31;
 1673     s31.x.n = 1;
 1674     S3 s32 = move(s31);
 1675     assert(s31.x.n == 0);
 1676     assert(s32.x.n == 1);
 1677 
 1678     // Issue 5661 test(2)
 1679     static struct S4
 1680     {
 1681         static struct X { int n = 0; this(this){n = 0;} }
 1682         X x;
 1683     }
 1684     static assert(hasElaborateCopyConstructor!S4);
 1685     S4 s41;
 1686     s41.x.n = 1;
 1687     S4 s42 = move(s41);
 1688     assert(s41.x.n == 0);
 1689     assert(s42.x.n == 1);
 1690 
 1691     // Issue 13990 test
 1692     class S5;
 1693 
 1694     S5 s51;
 1695     S5 s52 = s51;
 1696     S5 s53;
 1697     s53 = move(s52);
 1698     assert(s53 is s51);
 1699 }
 1700 
 1701 @system unittest
 1702 {
 1703     static struct S { int n = 0; ~this() @system { n = 0; } }
 1704     S a, b;
 1705     static assert(!__traits(compiles, () @safe { move(a, b); }));
 1706     static assert(!__traits(compiles, () @safe { move(a); }));
 1707     a.n = 1;
 1708     () @trusted { move(a, b); }();
 1709     assert(a.n == 0);
 1710     a.n = 1;
 1711     () @trusted { move(a); }();
 1712     assert(a.n == 0);
 1713 }
 1714 /+ this can't be tested in druntime, tests are still run in phobos
 1715 @safe unittest//Issue 6217
 1716 {
 1717     import std.algorithm.iteration : map;
 1718     auto x = map!"a"([1,2,3]);
 1719     x = move(x);
 1720 }
 1721 +/
 1722 @safe unittest// Issue 8055
 1723 {
 1724     static struct S
 1725     {
 1726         int x;
 1727         ~this()
 1728         {
 1729             assert(x == 0);
 1730         }
 1731     }
 1732     S foo(S s)
 1733     {
 1734         return move(s);
 1735     }
 1736     S a;
 1737     a.x = 0;
 1738     auto b = foo(a);
 1739     assert(b.x == 0);
 1740 }
 1741 
 1742 @system unittest// Issue 8057
 1743 {
 1744     int n = 10;
 1745     struct S
 1746     {
 1747         int x;
 1748         ~this()
 1749         {
 1750             // Access to enclosing scope
 1751             assert(n == 10);
 1752         }
 1753     }
 1754     S foo(S s)
 1755     {
 1756         // Move nested struct
 1757         return move(s);
 1758     }
 1759     S a;
 1760     a.x = 1;
 1761     auto b = foo(a);
 1762     assert(b.x == 1);
 1763 
 1764     // Regression 8171
 1765     static struct Array(T)
 1766     {
 1767         // nested struct has no member
 1768         struct Payload
 1769         {
 1770             ~this() {}
 1771         }
 1772     }
 1773     Array!int.Payload x = void;
 1774     move(x);
 1775     move(x, x);
 1776 }
 1777 
 1778 /**
 1779  * Similar to $(LREF move) but assumes `target` is uninitialized. This
 1780  * is more efficient because `source` can be blitted over `target`
 1781  * without destroying or initializing it first.
 1782  *
 1783  * Params:
 1784  *   source = value to be moved into target
 1785  *   target = uninitialized value to be filled by source
 1786  */
 1787 void moveEmplace(T)(ref T source, ref T target) @system
 1788 {
 1789     import core.stdc.string : memcpy, memset;
 1790     import core.internal.traits;
 1791 
 1792     // TODO: this assert pulls in half of phobos. we need to work out an alternative assert strategy.
 1793 //    static if (!is(T == class) && hasAliasing!T) if (!__ctfe)
 1794 //    {
 1795 //        import std.exception : doesPointTo;
 1796 //        assert(!doesPointTo(source, source), "Cannot move object with internal pointer.");
 1797 //    }
 1798 
 1799     static if (is(T == struct))
 1800     {
 1801         assert(&source !is &target, "source and target must not be identical");
 1802 
 1803         static if (hasElaborateAssign!T || !isAssignable!T)
 1804             memcpy(&target, &source, T.sizeof);
 1805         else
 1806             target = source;
 1807 
 1808         // If the source defines a destructor or a postblit hook, we must obliterate the
 1809         // object in order to avoid double freeing and undue aliasing
 1810         static if (hasElaborateDestructor!T || hasElaborateCopyConstructor!T)
 1811         {
 1812             // If T is nested struct, keep original context pointer
 1813             static if (__traits(isNested, T))
 1814                 enum sz = T.sizeof - (void*).sizeof;
 1815             else
 1816                 enum sz = T.sizeof;
 1817 
 1818             static if (__traits(isZeroInit, T))
 1819                 memset(&source, 0, sz);
 1820             else
 1821             {
 1822                 auto init = typeid(T).initializer();
 1823                 memcpy(&source, init.ptr, sz);
 1824             }
 1825         }
 1826     }
 1827     else static if (__traits(isStaticArray, T))
 1828     {
 1829         for (size_t i = 0; i < source.length; ++i)
 1830             move(source[i], target[i]);
 1831     }
 1832     else
 1833     {
 1834         // Primitive data (including pointers and arrays) or class -
 1835         // assignment works great
 1836         target = source;
 1837     }
 1838 }
 1839 
 1840 ///
 1841 pure nothrow @nogc @system unittest
 1842 {
 1843     static struct Foo
 1844     {
 1845     pure nothrow @nogc:
 1846         this(int* ptr) { _ptr = ptr; }
 1847         ~this() { if (_ptr) ++*_ptr; }
 1848         int* _ptr;
 1849     }
 1850 
 1851     int val;
 1852     Foo foo1 = void; // uninitialized
 1853     auto foo2 = Foo(&val); // initialized
 1854     assert(foo2._ptr is &val);
 1855 
 1856     // Using `move(foo2, foo1)` would have an undefined effect because it would destroy
 1857     // the uninitialized foo1.
 1858     // moveEmplace directly overwrites foo1 without destroying or initializing it first.
 1859     moveEmplace(foo2, foo1);
 1860     assert(foo1._ptr is &val);
 1861     assert(foo2._ptr is null);
 1862     assert(val == 0);
 1863 }
 1864 
 1865 // issue 18913
 1866 @safe unittest
 1867 {
 1868     static struct NoCopy
 1869     {
 1870         int payload;
 1871         ~this() { }
 1872         @disable this(this);
 1873     }
 1874 
 1875     static void f(NoCopy[2]) { }
 1876 
 1877     NoCopy[2] ncarray = [ NoCopy(1), NoCopy(2) ];
 1878 
 1879     static assert(!__traits(compiles, f(ncarray)));
 1880     f(move(ncarray));
 1881 }