core.lifetime - D Programming Language
Description: D Programming Language
Keywords: D programming language

Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Forums
  - IRC
  - Community Discord
  - Wiki
  - GitHub
  - Issues
  - Get involved
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# 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`)
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`)
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`)
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);

  Examples:

      // works with -betterC too:

      static extern (C++) class C
      {
          @nogc pure nothrow @safe:
          int i = 3;
          this(int i)
          {
              assert(this.i == 3);
              this.i = i;
          }
          int virtualGetI() { return i; }
      }

      align(__traits(classInstanceAlignment, C)) byte[__traits(classInstanceSize, C)] buffer;
      C c = emplace!C(buffer[], 42);
      assert(c.virtualGetI() == 42);

T* `emplace`(T, Args...)(void[] `chunk`, auto ref Args `args`)
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;
      }
      void[S.sizeof] buf = void;
      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`)
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)(ref return 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);

template `_d_delstructImpl`(T)
  Implementation of _d_delstruct and _d_delstructTrace
  pure nothrow @nogc @trusted void `_d_delstruct`(ref T `p`);
    This is called for a delete statement where the value being deleted is a pointer to a struct with a destructor but doesn't have an overloaded delete operator.
    Parameters:

    T `p` | pointer to the value to be deleted

    Bugs:
    This function template was ported from a much older runtime hook that bypassed safety, purity, and throwabilty checks. To prevent breaking existing code, this function template is temporarily declared @trusted until the implementation can be brought up to modern D expectations.
  alias `_d_delstructTrace` = _d_HookTraceImpl!(T, _d_delstruct, errorMessage);
    TraceGC wrapper around core.lifetime.d_delstructImpl.d_delstruct.
    Bugs:
    This function template was ported from a much older runtime hook that bypassed safety, purity, and throwabilty checks. To prevent breaking existing code, this function template is temporarily declared @trusted until the implementation can be brought up to modern D expectations.
@trusted T `_d_newThrowable`(T)()
if (is(T : Throwable) && (__traits(getLinkage, T) == "D"));
  Allocate an exception of type T from the exception pool. T must be Throwable or derived from it and cannot be a COM or C++ class.

  Note This function does not call the constructor of T because that would require forward!args, which causes errors with -dip1008. This inconvenience will be removed once -dip1008 works as intended.

  Returns:
  allocated instance of type T

Copyright © 1999-2022 by the D Language Foundation | Page generated by Ddoc on Mon Nov 14 18:06:30 2022