object - 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
  - 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.

# object

Category | Symbols
--- | ---
Arrays | assumeSafeAppend capacity dup idup reserve
Associative arrays | byKey byKeyValue byValue clear dup get keys rehash require update values
General | destroy hashOf imported noreturn
Classes | Error Exception Object opEquals Throwable
Type info | Interface ModuleInfo OffsetTypeInfo RTInfoImpl rtinfoNoPointers TypeInfo TypeInfo_Class

Forms the symbols available to all D programs. Includes Object, which is the root of the class object hierarchy. This module is implicitly imported.
License:
Boost License 1.0.
Authors:
Walter Bright, Sean Kelly

Source object.d

alias `noreturn` = `noreturn`;
  Bottom type. See spec/type, noreturn.
class `Object`;
  All D class objects inherit from Object.
  string `toString`();
    Convert Object to a human readable string.
  nothrow @trusted size_t `toHash`();
    Compute hash function for Object.
  int `opCmp`(Object `o`);
    Compare with another Object obj.
    Returns:

    this < obj | < 0
    this == obj | 0
    this > obj | > 0

  bool `opEquals`(Object `o`);
    Test whether this is equal to o. The default implementation only compares by identity (using the is operator). Generally, overrides and overloads for opEquals should attempt to compare objects by their contents. A class will most likely want to add an overload that takes your specific type as the argument and does the content comparison. Then you can override this and forward it to your specific typed overload with a cast. Remember to check for null on the typed overload.
    Examples:

        class Child {
           int contents;
           // the typed overload first. It can use all the attribute you want
           bool opEquals(const Child c) const @safe pure nothrow @nogc
           {
               if (c is null)
                   return false;
               return this.contents == c.contents;
           }

           // and now the generic override forwards with a cast
           override bool opEquals(Object o)
           {
               return this.opEquals(cast(Child) o);
           }
        }

  static Object `factory`(string `classname`);
    Create instance of class specified by the fully qualified name classname. The class must either have no constructors or have a default constructor.
    Returns:
    null if failed

    Example

        module foo.bar;

        class C
        {
            this() { x = 10; }
            int x;
        }

        void main()
        {
            auto c = cast(C)Object.factory("foo.bar.C");
            assert(c !is null && c.x == 10);
        }

bool `opEquals`(LHS, RHS)(LHS `lhs`, RHS `rhs`)
if ((is(LHS : const(Object)) || is(LHS : shared(const(Object)))) && (is(RHS : const(Object)) || is(RHS : shared(const(Object)))));
  Implementation for class opEquals override. Calls the class-defined methods after a null check. Please note this is not nogc right now, even if your implementation is, because of the typeinfo name string compare. This is because of dmd's dll implementation. However, it can infer to @safe if your class' opEquals is.
  Examples:
  If aliased to the same object or both null => equal

      class F { int flag; this(int flag) { this.flag = flag; } }

      F f;
      assert(f == f); // both null
      f = new F(1);
      assert(f == f); // both aliased to the same object

  Examples:
  If either is null => non-equal

      class F { int flag; this(int flag) { this.flag = flag; } }
      F f;
      assert(!(new F(0) == f));
      assert(!(f == new F(0)));

  Examples:
  If same exact type => one call to method opEquals This test passes @safe because it defines a new opEquals with @safe

      class F
      {
          int flag;

          this(int flag)
          {
              this.flag = flag;
          }

          bool opEquals(const F o) const @safe nothrow pure
          {
              return flag == o.flag;
          }
      }

      F f;
      assert(new F(0) == new F(0));
      assert(!(new F(0) == new F(1)));

  Examples:
  General case => symmetric calls to method opEquals

      int fEquals, gEquals;

      class Base
      {
          int flag;
          this(int flag)
          {
              this.flag = flag;
          }
      }

      class F : Base
      {
          this(int flag) { super(flag); }

          bool opEquals(const Base o) @safe
          {
              fEquals++;
              return flag == o.flag;
          }
      }

      class G : Base
      {
          this(int flag) { super(flag); }

          bool opEquals(const Base o) @safe
          {
              gEquals++;
              return flag == o.flag;
          }
      }

      assert(new F(1) == new G(1));
      assert(fEquals == 1);
      assert(gEquals == 1);

  Examples:
  This test shows an example for a comprehensive inheritance equality chain too.

      static class Base
      {
          int member;

          this(int member) pure @safe nothrow @nogc
          {
              this.member = member;
          }

          override bool opEquals(Object rhs) const
          {
              return this.opEquals(cast(Base) rhs);
          }

          bool opEquals(const Base rhs) const @nogc pure nothrow @safe
          {
              if (rhs is null)
                  return false;
              return this.member == rhs.member;
          }
      }

      // works through the direct class with attributes enabled, except for pure and nogc in the current TypeInfo implementation
      bool testThroughBase() nothrow @safe
      {
          Base b1 = new Base(0);
          Base b2 = new Base(0);
          assert(b1 == b2);
          Base b3 = new Base(1);
          assert(b1 != b3);
          return true;
      }

      static assert(testThroughBase());

      // also works through the base class interface thanks to the override, but no more attributes
      bool testThroughObject()
      {
          Object o1 = new Base(0);
          Object o2 = new Base(0);
          assert(o1 == o2);
          Object o3 = new Base(1);
          assert(o1 != o3);
          return true;
      }

      static assert(testThroughObject());

      // Each time you make a child, you want to override all old opEquals
      // and add a new overload for the new child.
      static class Child : Base
      {
          int member2;

          this(int member, int member2) pure @safe nothrow @nogc
          {
              super(member);
              this.member2 = member2;
          }

          // override the whole chain so it works consistently though any base
          override bool opEquals(Object rhs) const
          {
              return this.opEquals(cast(Child) rhs);
          }
          override bool opEquals(const Base rhs) const
          {
              return this.opEquals(cast(const Child) rhs);
          }
          // and then add the new overload, if necessary, to handle new members
          bool opEquals(const Child rhs) const @nogc pure nothrow @safe
          {
              if (rhs is null)
                  return false;
              // can call back to the devirtualized base test with implicit conversion
              // then compare the new member too. or we could have just compared the base
              // member directly here as well.
              return Base.opEquals(rhs) && this.member2 == rhs.member2;
          }

          // a mixin template, of course, could automate this.
      }

      bool testThroughChild()
      {
          Child a = new Child(0, 0);
          Child b = new Child(0, 1);
          assert(a != b);

          Base ba = a;
          Base bb = b;
          assert(ba != bb);

          Object oa = a;
          Object ob = b;
          assert(oa != ob);

          return true;
      }

      static assert(testThroughChild());

struct `Interface`;
  Information about an interface. When an object is accessed via an interface, an Interface* appears as the first entry in its vtbl.
  TypeInfo_Class `classinfo`;
    Class info returned by typeid for this interface (not for containing class)
  size_t `offset`;
    offset to Interface 'this' from Object 'this'
struct `OffsetTypeInfo`;
  Array of pairs giving the offset and type information for each member in an aggregate.
  size_t `offset`;
    Offset of member from start of object
  TypeInfo `ti`;
    TypeInfo for this member
abstract class `TypeInfo`;
  Runtime type information about a type. Can be retrieved for any type using a TypeidExpression.
  const nothrow @trusted size_t `getHash`(scope const void* `p`);
    Computes a hash of the instance of a type.
    Parameters:

    void* `p` | pointer to start of instance of the type

    Returns:
    the hash
    Bugs:
    fix https://issues.dlang.org/show_bug.cgi?id=12516 e.g. by changing this to a truly safe interface.
  const bool `equals`(in void* `p1`, in void* `p2`);
    Compares two instances for equality.
  const int `compare`(in void* `p1`, in void* `p2`);
    Compares two instances for <, ==, or >.
  const pure nothrow @nogc @property @safe size_t `tsize`();
    Returns size of the type.
  const void `swap`(void* `p1`, void* `p2`);
    Swaps two instances of the type.
  inout pure nothrow @nogc @property inout(TypeInfo) `next`();
    Get TypeInfo for 'next' type, as defined by what kind of type this is, null if none.
  abstract const pure nothrow @nogc @safe const(void)[] `initializer`();
    Return default initializer. If the type should be initialized to all zeros, an array with a null ptr and a length equal to the type size will be returned. For static arrays, this returns the default initializer for a single element of the array, use tsize to get the correct size.
  const pure nothrow @nogc @property @safe uint `flags`();
    Get flags for type: 1 means GC should scan for pointers, 2 means arg of this type is passed in SIMD register(s) if available
  const const(OffsetTypeInfo)[] `offTi`();
    Get type information on the contents of the type; null if not available
  const void `destroy`(void* `p`);
    Run the destructor on the object and all its sub-objects
  const void `postblit`(void* `p`);
    Run the postblit on the object and all its sub-objects
  const pure nothrow @nogc @property @safe size_t `talign`();
    Return alignment of type
  nothrow @safe int `argTypes`(out TypeInfo `arg1`, out TypeInfo `arg2`);
    Return internal info on arguments fitting into 8byte. See X86-64 ABI 3.2.3
  const pure nothrow @nogc @property @safe immutable(void)* `rtInfo`();
    Return info used by the garbage collector to do precise collection.
class `TypeInfo_Class`: object.TypeInfo;
  Runtime type information about a class. Can be retrieved from an object instance by using the typeid expression.
  byte[] `m_init`;
    class static initializer (init.length gives size in bytes of class)
  string `name`;
    class name
  void*[] `vtbl`;
    virtual function pointer table
  Interface[] `interfaces`;
    interfaces this class implements
  TypeInfo_Class `base`;
    base class
  static const(TypeInfo_Class) `find`(scope const char[] `classname`);
    Search all modules for TypeInfo_Class corresponding to classname.
    Returns:
    null if not found
  const Object `create`();
    Create instance of Object represented by 'this'.
  final const pure nothrow @nogc @trusted bool `isBaseOf`(scope const TypeInfo_Class `child`);
    Returns true if the class described by `child` derives from or is the class described by this TypeInfo_Class. Always returns false if the argument is null.
    Parameters:

    TypeInfo_Class `child` | TypeInfo for some class

    Returns:
    true if the class described by `child` derives from or is the class described by this TypeInfo_Class.
struct `ModuleInfo`;
  An instance of ModuleInfo is generated into the object file for each compiled module.
  It provides access to various aspects of the module. It is not generated for betterC.
  const pure nothrow @nogc @property void function() `tlsctor`();
    Returns:
    module constructor for thread locals, null if there isn't one
  const pure nothrow @nogc @property void function() `tlsdtor`();
    Returns:
    module destructor for thread locals, null if there isn't one
  const pure nothrow @nogc @property void* `xgetMembers`();
    Returns:
    address of a module's const(MemberInfo)[] getMembers(string) function, null if there isn't one
  const pure nothrow @nogc @property void function() `ctor`();
    Returns:
    module constructor, null if there isn't one
  const pure nothrow @nogc @property void function() `dtor`();
    Returns:
    module destructor, null if there isn't one
  const pure nothrow @nogc @property void function() `ictor`();
    Returns:
    module order independent constructor, null if there isn't one
  const pure nothrow @nogc @property void function() `unitTest`();
    Returns:
    address of function that runs the module's unittests, null if there isn't one
  const pure nothrow @nogc @property immutable(ModuleInfo*)[] `importedModules`() return;
    Returns:
    array of pointers to the ModuleInfo's of modules imported by this one
  const pure nothrow @nogc @property TypeInfo_Class[] `localClasses`() return;
    Returns:
    array of TypeInfo_Class references for classes defined in this module
  const pure nothrow @nogc @property string `name`() return;
    Returns:
    name of module, null if no name
class `Throwable`;
  The base class of all thrown objects.
  All thrown objects must inherit from Throwable. Class Exception, which derives from this class, represents the category of thrown objects that are safe to catch and handle. In principle, one should not catch Throwable objects that are not derived from Exception, as they represent unrecoverable runtime errors. Certain runtime guarantees may fail to hold when these errors are thrown, making it unsafe to continue execution after catching them.
  string `msg`;
    A message describing the error.
  string `file`;
    The file name of the D source code corresponding with where the error was thrown from.
  size_t `line`;
    The line number of the D source code corresponding with where the error was thrown from.
  TraceInfo `info`;
    The stack trace of where the error happened. This is an opaque object that can either be converted to string, or iterated over with foreach to extract the items in the stack trace (as strings).
  TraceDeallocator `infoDeallocator`;
    If set, this is used to deallocate the TraceInfo on destruction.
  inout pure nothrow @nogc @property scope @safe inout(Throwable) `next`() return;
    Returns:
    A reference to the next error in the list. This is used when a new Throwable is thrown from inside a catch block. The originally caught Exception will be chained to the new Throwable via this field.
  pure nothrow @nogc @property scope @safe void `next`(Throwable `tail`);
    Replace next in chain with `tail`. Use chainTogether instead if at all possible.
  final pure nothrow @nogc ref scope @system uint `refcount`() return;
    Returns:
    mutable reference to the reference count, which is 0 - allocated by the GC, 1 - allocated by d_newThrowable(), and >=2 which is the reference count + 1

    Note Marked as @system to discourage casual use of it.

  int `opApply`(scope int delegate(Throwable) `dg`);
    Loop over the chain of Throwables.
  static pure nothrow @nogc @system Throwable `chainTogether`(return scope Throwable `e1`, return scope Throwable `e2`);
    Append `e2` to chain of exceptions that starts with `e1`.
    Parameters:

    Throwable `e1` | start of chain (can be null)
    Throwable `e2` | second part of chain (can be null)

    Returns:
    Throwable that is at the start of the chain; null if both `e1` and `e2` are null
  string `toString`();
    Overrides Object.toString and returns the error message. Internally this forwards to the toString overload that takes a sink delegate.
  const void `toString`(scope void delegate(in char[]) `sink`);
    The Throwable hierarchy uses a toString overload that takes a sink delegate to avoid GC allocations, which cannot be performed in certain error situations. Override this toString method to customize the error message.
  const nothrow @safe const(char)[] `message`();
    Get the message describing the error.
    This getter is an alternative way to access the Exception's message, with the added advantage of being override-able in subclasses. Subclasses are hence free to do their own memory managements without being tied to the requirement of providing a string in a field.
    The default behavior is to return the Throwable.msg field.
    Returns:
    A message representing the cause of the Throwable
class `Exception`: object.Throwable;
  The base class of all errors that are safe to catch and handle.
  In principle, only thrown objects derived from this class are safe to catch inside a catch block. Thrown objects not derived from Exception represent runtime errors that should not be caught, as certain runtime guarantees may not hold, making it unsafe to continue program execution.
  Examples:

      bool gotCaught;
      try
      {
          throw new Exception("msg");
      }
      catch (Exception e)
      {
          gotCaught = true;
          assert(e.msg == "msg");
      }
      assert(gotCaught);

  pure nothrow @nogc @safe this(string `msg`, string `file` = __FILE__, size_t `line` = __LINE__, Throwable `nextInChain` = null);
    Creates a new instance of Exception. The nextInChain parameter is used internally and should always be null when passed by user code. This constructor does not automatically throw the newly-created Exception; the throw expression should be used for that purpose.
class `Error`: object.Throwable;
  The base class of all unrecoverable runtime errors.
  This represents the category of Throwable objects that are not safe to catch and handle. In principle, one should not catch Error objects, as they represent unrecoverable runtime errors. Certain runtime guarantees may fail to hold when these errors are thrown, making it unsafe to continue execution after catching them.
  Examples:

      bool gotCaught;
      try
      {
          throw new Error("msg");
      }
      catch (Error e)
      {
          gotCaught = true;
          assert(e.msg == "msg");
      }
      assert(gotCaught);

  pure nothrow @nogc @safe this(string `msg`, Throwable `nextInChain` = null);
    Creates a new instance of Error. The nextInChain parameter is used internally and should always be null when passed by user code. This constructor does not automatically throw the newly-created Error; the throw statement should be used for that purpose.
  Throwable `bypassedException`;
    The first Exception which was bypassed when this Error was thrown, or null if no Exceptions were pending.
void `clear`(Value, Key)(Value[Key] `aa`);
void `clear`(Value, Key)(Value[Key]* `aa`);
  Removes all remaining keys and values from an associative array.
  Parameters:

  Value[Key] `aa` | The associative array.

  Examples:

      auto aa = ["k1": 2];
      aa.clear;
      assert("k1" !in aa);

T `rehash`(T : Value[Key], Value, Key)(T `aa`);
T `rehash`(T : Value[Key], Value, Key)(T* `aa`);
T `rehash`(T : shared(Value[Key]), Value, Key)(T `aa`);
T `rehash`(T : shared(Value[Key]), Value, Key)(T* `aa`);
  Reorganizes the associative array in place so that lookups are more efficient.
  Parameters:

  T `aa` | The associative array.

  Returns:
  The rehashed associative array.
V[K] `dup`(T : V[K], K, V)(T `aa`);
V[K] `dup`(T : V[K], K, V)(T* `aa`);
  Creates a new associative array of the same size and copies the contents of the associative array into it.
  Parameters:

  T `aa` | The associative array.

  Examples:

      auto aa = ["k1": 2];
      auto a2 = aa.dup;
      aa["k2"] = 3;
      assert("k2" !in a2);

pure nothrow @nogc @safe auto `byKey`(T : V[K], K, V)(T `aa`);
pure nothrow @nogc auto `byKey`(T : V[K], K, V)(T* `aa`);
  Returns a forward range which will iterate over the keys of the associative array. The keys are returned by reference.
  If structural changes are made to the array (removing or adding keys), all ranges previously obtained through this function are invalidated. The following example program will dereference a null pointer:

       import std.stdio : writeln;

       auto dict = ["k1": 1, "k2": 2];
       auto keyRange = dict.byKey;
       dict.clear;
       writeln(keyRange.front);    // Segmentation fault

  Parameters:

  T `aa` | The associative array.

  Returns:
  A forward range referencing the keys of the associative array.
  Examples:

      auto dict = [1: "v1", 2: "v2"];
      int sum;
      foreach (v; dict.byKey)
          sum += v;

      assert(sum == 3);

pure nothrow @nogc @safe auto `byValue`(T : V[K], K, V)(T `aa`);
pure nothrow @nogc auto `byValue`(T : V[K], K, V)(T* `aa`);
  Returns a forward range which will iterate over the values of the associative array. The values are returned by reference.
  If structural changes are made to the array (removing or adding keys), all ranges previously obtained through this function are invalidated. The following example program will dereference a null pointer:

       import std.stdio : writeln;

       auto dict = ["k1": 1, "k2": 2];
       auto valueRange = dict.byValue;
       dict.clear;
       writeln(valueRange.front);    // Segmentation fault

  Parameters:

  T `aa` | The associative array.

  Returns:
  A forward range referencing the values of the associative array.
  Examples:

      auto dict = ["k1": 1, "k2": 2];
      int sum;
      foreach (v; dict.byValue)
          sum += v;

      assert(sum == 3);

pure nothrow @nogc @safe auto `byKeyValue`(T : V[K], K, V)(T `aa`);
pure nothrow @nogc auto `byKeyValue`(T : V[K], K, V)(T* `aa`);
  Returns a forward range which will iterate over the key-value pairs of the associative array. The returned pairs are represented by an opaque type with .key and .value properties for accessing references to the key and value of the pair, respectively.
  If structural changes are made to the array (removing or adding keys), all ranges previously obtained through this function are invalidated. The following example program will dereference a null pointer:

       import std.stdio : writeln;

       auto dict = ["k1": 1, "k2": 2];
       auto kvRange = dict.byKeyValue;
       dict.clear;
       writeln(kvRange.front.key, ": ", kvRange.front.value);    // Segmentation fault

  Note that this is a low-level interface to iterating over the associative array and is not compatible withth the Tuple type in Phobos. For compatibility with Tuple, use std.array.byPair instead.
  Parameters:

  T `aa` | The associative array.

  Returns:
  A forward range referencing the pairs of the associative array.
  Examples:

      auto dict = ["k1": 1, "k2": 2];
      int sum;
      foreach (e; dict.byKeyValue)
      {
          assert(e.key[1] == e.value + '0');
          sum += e.value;
      }

      assert(sum == 3);

@property Key[] `keys`(T : Value[Key], Value, Key)(T `aa`);
@property Key[] `keys`(T : Value[Key], Value, Key)(T* `aa`);
  Returns a newly allocated dynamic array containing a copy of the keys from the associative array.
  Parameters:

  T `aa` | The associative array.

  Returns:
  A dynamic array containing a copy of the keys.
  Examples:

      auto aa = [1: "v1", 2: "v2"];
      int sum;
      foreach (k; aa.keys)
          sum += k;

      assert(sum == 3);

@property Value[] `values`(T : Value[Key], Value, Key)(T `aa`);
@property Value[] `values`(T : Value[Key], Value, Key)(T* `aa`);
  Returns a newly allocated dynamic array containing a copy of the values from the associative array.
  Parameters:

  T `aa` | The associative array.

  Returns:
  A dynamic array containing a copy of the values.
  Examples:

      auto aa = ["k1": 1, "k2": 2];
      int sum;
      foreach (e; aa.values)
          sum += e;

      assert(sum == 3);

inout(V) `get`(K, V)(inout(V[K]) `aa`, K `key`, lazy inout(V) `defaultValue`);
inout(V) `get`(K, V)(inout(V[K])* `aa`, K `key`, lazy inout(V) `defaultValue`);
  Looks up key; if it exists returns corresponding value else evaluates and returns defaultValue.
  Parameters:

  inout(V[K]) `aa` | The associative array.
  K `key` | The key.
  inout(V) `defaultValue` | The default value.

  Returns:
  The value.
  Examples:

      auto aa = ["k1": 1];
      assert(aa.get("k1", 0) == 1);
      assert(aa.get("k2", 0) == 0);

ref V `require`(K, V)(ref V[K] `aa`, K `key`, lazy V `value` = V.init);
  Looks up key; if it exists returns corresponding value else evaluates value, adds it to the associative array and returns it.
  Parameters:

  V[K] `aa` | The associative array.
  K `key` | The key.
  V `value` | The required value.

  Returns:
  The value.
  Examples:

      auto aa = ["k1": 1];
      assert(aa.require("k1", 0) == 1);
      assert(aa.require("k2", 0) == 0);
      assert(aa["k2"] == 0);

void `update`(K, V, C, U)(ref V[K] `aa`, K `key`, scope C `create`, scope U `update`)
if (is(typeof(`create`()) : V) && (is(typeof(`update`(`aa`[K.init])) : V) || is(typeof(`update`(`aa`[K.init])) == void)));
  Calls `create` if `key` doesn't exist in the associative array, otherwise calls `update`. `create` returns a corresponding value for `key`. `update` accepts a key parameter. If it returns a value, the value is set for `key`.
  Parameters:

  V[K] `aa` | The associative array.
  K `key` | The key.
  C `create` | The callable to create a value for `key`. Must return V.
  U `update` | The callable to call if `key` exists. Takes a K argument, returns a V or void.

  Examples:

      int[string] aa;

      // create
      aa.update("key",
          () => 1,
          (int) {} // not executed
          );
      assert(aa["key"] == 1);

      // update value by ref
      aa.update("key",
          () => 0, // not executed
          (ref int v) {
              v += 1;
          });
      assert(aa["key"] == 2);

      // update from return value
      aa.update("key",
          () => 0, // not executed
          (int v) => v * 2
          );
      assert(aa["key"] == 4);

      // 'update' without changing value
      aa.update("key",
          () => 0, // not executed
          (int) {
              // do something else
          });
      assert(aa["key"] == 4);

size_t `hashOf`(T)(auto ref T `arg`, size_t `seed`);
size_t `hashOf`(T)(auto ref T `arg`);
  Calculates the hash value of `arg` with an optional `seed` initial value. The result might not be equal to typeid(T).getHash(&`arg`).
  Parameters:

  T `arg` | argument to calculate the hash value of
  size_t `seed` | optional `seed` value (may be used for hash chaining)

  Return calculated hash value of `arg`

  Examples:

      class MyObject
      {
          size_t myMegaHash() const @safe pure nothrow
          {
              return 42;
          }
      }
      struct Test
      {
          int a;
          string b;
          MyObject c;
          size_t toHash() const pure nothrow
          {
              size_t hash = a.hashOf();
              hash = b.hashOf(hash);
              size_t h1 = c.myMegaHash();
              hash = h1.hashOf(hash); //Mix two hash values
              return hash;
          }
      }

immutable size_t[pointerBitmap.length] `RTInfoImpl`(size_t[] pointerBitmap);
  Create RTInfo for type T
enum immutable(void)* `rtinfoNoPointers`;
  shortcuts for the precise GC, also generated by the compiler used instead of the actual pointer bitmap
@property auto `dup`(T)(T[] `a`)
if (!is(const(T) : T));
@property T[] `dup`(T)(const(T)[] `a`)
if (is(const(T) : T));
  Provide the .dup array property.
  Examples:

      auto arr = [1, 2];
      auto arr2 = arr.dup;
      arr[0] = 0;
      assert(arr == [0, 2]);
      assert(arr2 == [1, 2]);

@property immutable(T)[] `idup`(T)(T[] `a`);
@property immutable(T)[] `idup`(T : void)(const(T)[] `a`);
  Provide the .idup array property.
  Examples:

      char[] arr = ['a', 'b', 'c'];
      string s = arr.idup;
      arr[0] = '.';
      assert(s == "abc");

pure nothrow @property @trusted size_t `capacity`(T)(T[] `arr`);
  (Property) Gets the current capacity of a slice. The capacity is the size that the slice can grow to before the underlying array must be reallocated or extended.
  If an append must reallocate a slice with no possibility of extension, then 0 is returned. This happens when the slice references a static array, or if another slice references elements past the end of the current slice.

  Note The capacity of a slice may be impacted by operations on other slices.

  Examples:

      //Static array slice: no capacity
      int[4] sarray = [1, 2, 3, 4];
      int[]  slice  = sarray[];
      assert(sarray.capacity == 0);
      //Appending to slice will reallocate to a new array
      slice ~= 5;
      assert(slice.capacity >= 5);

      //Dynamic array slices
      int[] a = [1, 2, 3, 4];
      int[] b = a[1 .. $];
      int[] c = a[1 .. $ - 1];
      debug(SENTINEL) {} else // non-zero capacity very much depends on the array and GC implementation
      {
          assert(a.capacity != 0);
          assert(a.capacity == b.capacity + 1); //both a and b share the same tail
      }
      assert(c.capacity == 0);              //an append to c must relocate c.

pure nothrow @trusted size_t `reserve`(T)(ref T[] `arr`, size_t `newcapacity`);
  Reserves capacity for a slice. The capacity is the size that the slice can grow to before the underlying array must be reallocated or extended.
  Returns:
  The new capacity of the array (which may be larger than the requested capacity).
  Examples:

      //Static array slice: no capacity. Reserve relocates.
      int[4] sarray = [1, 2, 3, 4];
      int[]  slice  = sarray[];
      auto u = slice.reserve(8);
      assert(u >= 8);
      assert(&sarray[0] !is &slice[0]);
      assert(slice.capacity == u);

      //Dynamic array slices
      int[] a = [1, 2, 3, 4];
      a.reserve(8); //prepare a for appending 4 more items
      auto p = &a[0];
      u = a.capacity;
      a ~= [5, 6, 7, 8];
      assert(p == &a[0]);      //a should not have been reallocated
      assert(u == a.capacity); //a should not have been extended

nothrow ref @system inout(T[]) `assumeSafeAppend`(T)(auto ref inout(T[]) `arr`);
  Assume that it is safe to append to this array. Appends made to this array after calling this function may append in place, even if the array was a slice of a larger array to begin with.
  Use this only when it is certain there are no elements in use beyond the array in the memory block. If there are, those elements will be overwritten by appending to this array.

  Warning Calling this function, and then using references to data located after the given array results in undefined behavior.

  Returns:
  The input is returned.
  Examples:

      int[] a = [1, 2, 3, 4];

      // Without assumeSafeAppend. Appending relocates.
      int[] b = a [0 .. 3];
      b ~= 5;
      assert(a.ptr != b.ptr);

      debug(SENTINEL) {} else
      {
          // With assumeSafeAppend. Appending overwrites.
          int[] c = a [0 .. 3];
          c.assumeSafeAppend() ~= 5;
          assert(a.ptr == c.ptr);
      }

void `destroy`(bool initialize = true, T)(ref T `obj`)
if (is(T == struct));
void `destroy`(bool initialize = true, T)(T `obj`)
if (is(T == class));
void `destroy`(bool initialize = true, T)(T `obj`)
if (is(T == interface));
void `destroy`(bool initialize = true, T)(ref T `obj`)
if (__traits(isStaticArray, T));
void `destroy`(bool initialize = true, T)(ref T `obj`)
if (!is(T == struct) && !is(T == interface) && !is(T == class) && !__traits(isStaticArray, T));
  Destroys the given object and optionally resets to initial state. It's used to destroy an object, calling its destructor or finalizer so it no longer references any other objects. It does not initiate a GC cycle or free any GC memory. If initialize is supplied false, the object is considered invalid after destruction, and should not be referenced.
  Examples:
  Reference type demonstration

      class C
      {
          struct Agg
          {
              static int dtorCount;

              int x = 10;
              ~this() { dtorCount++; }
          }

          static int dtorCount;

          string s = "S";
          Agg a;
          ~this() { dtorCount++; }
      }

      C c = new C();
      assert(c.dtorCount == 0);   // destructor not yet called
      assert(c.s == "S");         // initial state `c.s` is `"S"`
      assert(c.a.dtorCount == 0); // destructor not yet called
      assert(c.a.x == 10);        // initial state `c.a.x` is `10`
      c.s = "T";
      c.a.x = 30;
      assert(c.s == "T");         // `c.s` is `"T"`
      destroy(c);
      assert(c.dtorCount == 1);   // `c`'s destructor was called
      assert(c.s == "S");         // `c.s` is back to its inital state, `"S"`
      assert(c.a.dtorCount == 1); // `c.a`'s destructor was called
      assert(c.a.x == 10);        // `c.a.x` is back to its inital state, `10`

      // check C++ classes work too!
      extern (C++) class CPP
      {
          struct Agg
          {
              __gshared int dtorCount;

              int x = 10;
              ~this() { dtorCount++; }
          }

          __gshared int dtorCount;

          string s = "S";
          Agg a;
          ~this() { dtorCount++; }
      }

      CPP cpp = new CPP();
      assert(cpp.dtorCount == 0);   // destructor not yet called
      assert(cpp.s == "S");         // initial state `cpp.s` is `"S"`
      assert(cpp.a.dtorCount == 0); // destructor not yet called
      assert(cpp.a.x == 10);        // initial state `cpp.a.x` is `10`
      cpp.s = "T";
      cpp.a.x = 30;
      assert(cpp.s == "T");         // `cpp.s` is `"T"`
      destroy!false(cpp);           // destroy without initialization
      assert(cpp.dtorCount == 1);   // `cpp`'s destructor was called
      assert(cpp.s == "T");         // `cpp.s` is not initialized
      assert(cpp.a.dtorCount == 1); // `cpp.a`'s destructor was called
      assert(cpp.a.x == 30);        // `cpp.a.x` is not initialized
      destroy(cpp);
      assert(cpp.dtorCount == 2);   // `cpp`'s destructor was called again
      assert(cpp.s == "S");         // `cpp.s` is back to its inital state, `"S"`
      assert(cpp.a.dtorCount == 2); // `cpp.a`'s destructor was called again
      assert(cpp.a.x == 10);        // `cpp.a.x` is back to its inital state, `10`

  Examples:
  Value type demonstration

      int i;
      assert(i == 0);           // `i`'s initial state is `0`
      i = 1;
      assert(i == 1);           // `i` changed to `1`
      destroy!false(i);
      assert(i == 1);           // `i` was not initialized
      destroy(i);
      assert(i == 0);           // `i` is back to its initial state `0`

template `imported`(string moduleName)
  Provides an "inline import", i.e. an import that is only available for a limited lookup. For example:

      void fun(imported!"std.stdio".File input)
      {
          ... use File from std.stdio normally ...
      }

  There is no need to import std.stdio at top level, so fun carries its own dependencies. The same approach can be used for template constraints:

      void fun(T)(imported!"std.stdio".File input, T value)
      if (imported!"std.traits".isIntegral!T)
      {
          ...
      }

  An inline import may be used in conjunction with the with statement as well. Inside the scope controlled by with, all symbols in the imported module are made available:

      void fun()
      {
          with (imported!"std.datetime")
          with (imported!"std.stdio")
          {
              Clock.currTime.writeln;
          }
      }

  The advantages of inline imports over top-level uses of the import declaration are the following:
  - The `imported` template specifies dependencies at declaration level, not at module level. This allows reasoning about the dependency cost of declarations in separation instead of aggregated at module level.
  - Declarations using `imported` are easier to move around because they don't require top-level context, making for simpler and quicker refactorings.
  - Declarations using `imported` scale better with templates. This is because templates that are not instantiated do not have their parameters and constraints instantiated, so additional modules are not imported without necessity. This makes the cost of unused templates negligible. Dependencies are pulled on a need basis depending on the declarations used by client code.
  The use of `imported` also has drawbacks:
  - If most declarations in a module need the same imports, then factoring them at top level, outside the declarations, is simpler than repeating them.
  - Traditional dependency-tracking tools such as make and other build systems assume file-level dependencies and need special tooling (such as rdmd) in order to work efficiently.
  - Dependencies at the top of a module are easier to inspect quickly than dependencies spread throughout the module.
  See Also:
  The forum discussion that led to the creation of the `imported` facility. Credit is due to Daniel Nielsen and Dominikus Dittes Scherkl.

Copyright © 1999-2023 by the D Language Foundation | Page generated by Ddoc on Fri Jun 2 08:58:43 2023