Data to copy.
Where to copy into. The destructor, if any, is invoked before the copy is performed.
For non-struct types, move just performs target = source:
Object obj1 = new Object; Object obj2 = obj1; Object obj3; move(obj2, obj3); assert(obj3 is obj1); // obj2 unchanged assert(obj2 is obj1);
1 // Structs without destructors are simply copied 2 struct S1 3 { 4 int a = 1; 5 int b = 2; 6 } 7 S1 s11 = { 10, 11 }; 8 S1 s12; 9 10 move(s11, s12); 11 12 assert(s12 == S1(10, 11)); 13 assert(s11 == s12); 14 15 // But structs with destructors or postblits are reset to their .init value 16 // after copying to the target. 17 struct S2 18 { 19 int a = 1; 20 int b = 2; 21 22 ~this() pure nothrow @safe @nogc { } 23 } 24 S2 s21 = { 3, 4 }; 25 S2 s22; 26 27 move(s21, s22); 28 29 assert(s21 == S2(1, 2)); 30 assert(s22 == S2(3, 4));
Non-copyable structs can still be moved:
struct S { int a = 1; @disable this(this); ~this() pure nothrow @safe @nogc {} } S s1; s1.a = 2; S s2 = move(s1); assert(s1.a == 1); assert(s2.a == 2);
opPostMove will be called if defined:
struct S { int a; void opPostMove(const ref S old) { assert(a == old.a); a++; } } S s1; s1.a = 41; S s2 = move(s1); assert(s2.a == 42);
Moves source into target, via a destructive copy when necessary.
If T is a struct with a destructor or postblit defined, source is reset to its .init value after it is moved into target, otherwise it is left unchanged.
Preconditions: If source has internal pointers that point to itself and doesn't define opPostMove, it cannot be moved, and will trigger an assertion failure.