containers.internal.storage_type
Templates for determining data storage types.
License
-
Declaration
template
ContainerStorageType
(T)This template is used to determine the type that a container should contain a given type T.
Discussion
In many cases it is not possible for a Container!(T) to hold T if T is const or immutable. For instance, a binary heap will need to rearrange items in its internal data storage, or an unrolled list will need to move items within a node.
All containers must only return const references or const copies of data stored within them if the contained type is const. This template exists because containers may need to move entire items but not change internal state of those items and D's type system would otherwise not allow this.
- If T is mutable (i.e. not immutable or const), this template aliases itself to T.
- Class and Interface types: Rebindable is used. Using this properly in a container requires that issue 8663 be fixed. Without this fix it is not possible to implement containers such as a binary heap that must compare container elements using opCmp()
- Struct and Union types:
- Stuct and union types that have elaborate constructors, elaboriate opAssign, or a destructor cannot be stored in containers because there may be user-visible effects of discarding const or immutable on these struct types.
- Other struct and union types will be stored as non-const versions of themselves.
- Basic types: Basic types will have their const or immutable status removed.
- Pointers: Pointers will have their type constructors shifted. E.g. const(int*) becomes const(int)*
Examples
static assert (is (ContainerStorageType!(int) == int)); static assert (is (ContainerStorageType!(const int) == int));
Examples
import std.typecons : Rebindable; static assert (is (ContainerStorageType!(Object) == Object)); static assert (is (ContainerStorageType!(const(Object)) == Rebindable!(const(Object))));
Examples
struct A { int foo; } struct B { void opAssign(typeof(this)) { this.foo *= 2; } int foo;} // A can be stored easily because it is plain data static assert (is (ContainerStorageType!(A) == A)); static assert (is (ContainerStorageType!(const(A)) == A)); // const(B) cannot be stored in the container because of its // opAssign. Casting away const could lead to some very unexpected // behavior. static assert (!is (typeof(ContainerStorageType!(const(B))))); // Mutable B is not a problem static assert (is (ContainerStorageType!(B) == B)); // Arrays can be stored because the entire pointer-length pair is moved as // a unit. static assert (is (ContainerStorageType!(const(int[])) == const(int)[]));
Examples
static assert (is (ContainerStorageType!(const(int*)) == const(int)*));