core.lifetime

pure nothrow @safe T* emplace(T)(T* chunk);

Given a pointer chunk to uninitialized memory (but already typed as T), constructs an object of non-class type T at that address. If T is a class, initializes the class reference to null.

Returns:
A pointer to the newly constructed object (which is the same as chunk).
Examples:
static struct S
{
    int i = 42;
}
S[2] s2 = void;
emplace(&s2);
assert(s2[0].i == 42 && s2[1].i == 42);
Examples:
interface I {}
class K : I {}

K k = void;
emplace(&k);
assert(k is null);

I i = void;
emplace(&i);
assert(i is null);
T* emplace(T, Args...)(T* chunk, auto ref Args args)
Constraints: if (is(T == struct) || Args.length == 1);

Given a pointer chunk to uninitialized memory (but already typed as a non-class type T), constructs an object of type T at that address from arguments args. If T is a class, initializes the class reference to args[0]. This function can be @trusted if the corresponding constructor of T is @safe.

Returns:
A pointer to the newly constructed object (which is the same as chunk).
Examples:
int a;
int b = 42;
assert(*emplace!int(&a, b) == 42);
T emplace(T, Args...)(T chunk, auto ref Args args)
Constraints: if (is(T == class));

Given a raw memory area chunk (but already typed as a class type T), constructs an object of class type T at that address. The constructor is passed the arguments Args. If T is an inner class whose outer field can be used to access an instance of the enclosing class, then Args must not be empty, and the first member of it must be a valid initializer for that outer field. Correct initialization of this field is essential to access members of the outer class inside T methods.

Note
This function is @safe if the corresponding constructor of T is @safe.
Returns:
The newly constructed object.
Examples:
() @safe {
    class SafeClass
    {
        int x;
        @safe this(int x) { this.x = x; }
    }

    auto buf = new void[__traits(classInstanceSize, SafeClass)];
    auto support = (() @trusted => cast(SafeClass)(buf.ptr))();
    auto safeClass = emplace!SafeClass(support, 5);
    assert(safeClass.x == 5);

    class UnsafeClass
    {
        int x;
        @system this(int x) { this.x = x; }
    }

    auto buf2 = new void[__traits(classInstanceSize, UnsafeClass)];
    auto support2 = (() @trusted => cast(UnsafeClass)(buf2.ptr))();
    static assert(!__traits(compiles, emplace!UnsafeClass(support2, 5)));
    static assert(!__traits(compiles, emplace!UnsafeClass(buf2, 5)));
}();
T emplace(T, Args...)(void[] chunk, auto ref Args args)
Constraints: if (is(T == class));

Given a raw memory area chunk, constructs an object of class type T at that address. The constructor is passed the arguments Args. If T is an inner class whose outer field can be used to access an instance of the enclosing class, then Args must not be empty, and the first member of it must be a valid initializer for that outer field. Correct initialization of this field is essential to access members of the outer class inside T methods.

Preconditions
chunk must be at least as large as T needs and should have an alignment multiple of T's alignment. (The size of a class instance is obtained by using _traits(classInstanceSize, T)).
Note
This function can be @trusted if the corresponding constructor of T is @safe.
Returns:
The newly constructed object.
Examples:
static class C
{
    int i;
    this(int i){this.i = i;}
}
auto buf = new void[__traits(classInstanceSize, C)];
auto c = emplace!C(buf, 5);
assert(c.i == 5);
T* emplace(T, Args...)(void[] chunk, auto ref Args args)
Constraints: if (!is(T == class));

Given a raw memory area chunk, constructs an object of non-class type T at that address. The constructor is passed the arguments args, if any.

Preconditions
chunk must be at least as large as T needs and should have an alignment multiple of T's alignment.
Note
This function can be @trusted if the corresponding constructor of T is @safe.
Returns:
A pointer to the newly constructed object.
Examples:
struct S
{
    int a, b;
}
auto buf = new void[S.sizeof];
S s;
s.a = 42;
s.b = 43;
auto s1 = emplace!S(buf, s);
assert(s1.a == 42 && s1.b == 43);
@system void copyEmplace(S, T)(ref S source, ref T target)
Constraints: if (is(immutable(S) == immutable(T)));

Emplaces a copy of the specified source value into uninitialized memory, i.e., simulates T target = source copy-construction for cases where the target memory is already allocated and to be initialized with a copy.

Parameters:
S source value to be copied into target
T target uninitialized value to be initialized with a copy of source
Examples:
int source = 123;
int target = void;
copyEmplace(source, target);
assert(target == 123);
Examples:
immutable int[1][1] source = [ [123] ];
immutable int[1][1] target = void;
copyEmplace(source, target);
assert(target[0][0] == 123);
Examples:
struct S
{
    int x;
    void opAssign(const scope ref S rhs) @safe pure nothrow @nogc
    {
        assert(0);
    }
}

S source = S(42);
S target = void;
copyEmplace(source, target);
assert(target.x == 42);
template forward(args...)

Forwards function arguments while keeping out, ref, and lazy on the parameters.

Parameters:
args a parameter list or an std.meta.AliasSeq.
Returns:
An AliasSeq of args with out, ref, and lazy saved.
Examples:
class C
{
    static int foo(int n) { return 1; }
    static int foo(ref int n) { return 2; }
}

// with forward
int bar()(auto ref int x) { return C.foo(forward!x); }

// without forward
int baz()(auto ref int x) { return C.foo(x); }

int i;
assert(bar(1) == 1);
assert(bar(i) == 2);

assert(baz(1) == 2);
assert(baz(i) == 2);
Examples:
void foo(int n, ref string s) { s = null; foreach (i; 0 .. n) s ~= "Hello"; }

// forwards all arguments which are bound to parameter tuple
void bar(Args...)(auto ref Args args) { return foo(forward!args); }

// forwards all arguments with swapping order
void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }

string s;
bar(1, s);
assert(s == "Hello");
baz(s, 2);
assert(s == "HelloHello");
Examples:
struct X {
    int i;
    this(this)
    {
        ++i;
    }
}

struct Y
{
    private X x_;
    this()(auto ref X x)
    {
        x_ = forward!x;
    }
}

struct Z
{
    private const X x_;
    this()(auto ref X x)
    {
        x_ = forward!x;
    }
    this()(auto const ref X x)
    {
        x_ = forward!x;
    }
}

X x;
const X cx;
auto constX = (){ const X x; return x; };
static assert(__traits(compiles, { Y y = x; }));
static assert(__traits(compiles, { Y y = X(); }));
static assert(!__traits(compiles, { Y y = cx; }));
static assert(!__traits(compiles, { Y y = constX(); }));
static assert(__traits(compiles, { Z z = x; }));
static assert(__traits(compiles, { Z z = X(); }));
static assert(__traits(compiles, { Z z = cx; }));
static assert(__traits(compiles, { Z z = constX(); }));


Y y1 = x;
// ref lvalue, copy
assert(y1.x_.i == 1);
Y y2 = X();
// rvalue, move
assert(y2.x_.i == 0);

Z z1 = x;
// ref lvalue, copy
assert(z1.x_.i == 1);
Z z2 = X();
// rvalue, move
assert(z2.x_.i == 0);
Z z3 = cx;
// ref const lvalue, copy
assert(z3.x_.i == 1);
Z z4 = constX();
// const rvalue, copy
assert(z4.x_.i == 1);
void move(T)(ref T source, ref T target);

T move(T)(return ref scope T source);

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.
Parameters:
T source Data to copy.
T target 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);
Examples:
// 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));
Examples:
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);
@system void moveEmplace(T)(ref T source, ref T target);

Similar to move but assumes target is uninitialized. This is more efficient because source can be blitted over target without destroying or initializing it first.

Parameters:
T source value to be moved into target
T target uninitialized value to be filled by source
Examples:
static struct Foo
{
pure nothrow @nogc:
    this(int* ptr) { _ptr = ptr; }
    ~this() { if (_ptr) ++*_ptr; }
    int* _ptr;
}

int val;
Foo foo1 = void; // uninitialized
auto foo2 = Foo(&val); // initialized
assert(foo2._ptr is &val);

// Using `move(foo2, foo1)` would have an undefined effect because it would destroy
// the uninitialized foo1.
// moveEmplace directly overwrites foo1 without destroying or initializing it first.
moveEmplace(foo2, foo1);
assert(foo1._ptr is &val);
assert(foo2._ptr is null);
assert(val == 0);

© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/core_lifetime.html