The OpenD Programming Language

move

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.

  1. void move(T source, T target)
    void
    move
    (
    T
    )
    (
    ref T source
    ,
    ref T target
    )
  2. T move(T source)

Parameters

source T

Data to copy.

target T

Where to copy into. The destructor, if any, is invoked before the copy is performed.

Examples

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);
// Structs without destructors are simply copied
struct S1
{
    int a = 1;
    int b = 2;
}
S1 s11 = { 10, 11 };
S1 s12;

move(s11, s12);

assert(s12 == S1(10, 11));
assert(s11 == s12);

// But structs with destructors or postblits are reset to their .init value
// after copying to the target.
struct S2
{
    int a = 1;
    int b = 2;

    ~this() pure nothrow @safe @nogc { }
}
S2 s21 = { 3, 4 };
S2 s22;

move(s21, s22);

assert(s21 == S2(1, 2));
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);

Meta