| // Written in the D programming language. | |
| /** | |
| This module defines generic containers. | |
| Construction: | |
| To implement the different containers both struct and class based | |
| approaches have been used. $(REF make, std,container,util) allows for | |
| uniform construction with either approach. | |
| --- | |
| import std.container; | |
| // Construct a red-black tree and an array both containing the values 1, 2, 3. | |
| // RedBlackTree should typically be allocated using `new` | |
| RedBlackTree!int rbTree = new RedBlackTree!int(1, 2, 3); | |
| // But `new` should not be used with Array | |
| Array!int array = Array!int(1, 2, 3); | |
| // `make` hides the differences | |
| RedBlackTree!int rbTree2 = make!(RedBlackTree!int)(1, 2, 3); | |
| Array!int array2 = make!(Array!int)(1, 2, 3); | |
| --- | |
| Note that `make` can infer the element type from the given arguments. | |
| --- | |
| import std.container; | |
| auto rbTree = make!RedBlackTree(1, 2, 3); // RedBlackTree!int | |
| auto array = make!Array("1", "2", "3"); // Array!string | |
| --- | |
| Reference_semantics: | |
| All containers have reference semantics, which means that after | |
| assignment both variables refer to the same underlying data. | |
| To make a copy of a container, use the `c.dup` container primitive. | |
| --- | |
| import std.container, std.range; | |
| Array!int originalArray = make!(Array!int)(1, 2, 3); | |
| Array!int secondArray = originalArray; | |
| assert(equal(originalArray[], secondArray[])); | |
| // changing one instance changes the other one as well! | |
| originalArray[0] = 12; | |
| assert(secondArray[0] == 12); | |
| // secondArray now refers to an independent copy of originalArray | |
| secondArray = originalArray.dup; | |
| secondArray[0] = 1; | |
| // assert that originalArray has not been affected | |
| assert(originalArray[0] == 12); | |
| --- | |
| $(B Attention:) If the container is implemented as a class, using an | |
| uninitialized instance can cause a null pointer dereference. | |
| --- | |
| import std.container; | |
| RedBlackTree!int rbTree; | |
| rbTree.insert(5); // null pointer dereference | |
| --- | |
| Using an uninitialized struct-based container will work, because the struct | |
| intializes itself upon use; however, up to this point the container will not | |
| have an identity and assignment does not create two references to the same | |
| data. | |
| --- | |
| import std.container; | |
| // create an uninitialized array | |
| Array!int array1; | |
| // array2 does _not_ refer to array1 | |
| Array!int array2 = array1; | |
| array2.insertBack(42); | |
| // thus array1 will not be affected | |
| assert(array1.empty); | |
| // after initialization reference semantics work as expected | |
| array1 = array2; | |
| // now affects array2 as well | |
| array1.removeBack(); | |
| assert(array2.empty); | |
| --- | |
| It is therefore recommended to always construct containers using | |
| $(REF make, std,container,util). | |
| This is in fact necessary to put containers into another container. | |
| For example, to construct an `Array` of ten empty `Array`s, use | |
| the following that calls `make` ten times. | |
| --- | |
| import std.container, std.range; | |
| auto arrOfArrs = make!Array(generate!(() => make!(Array!int)).take(10)); | |
| --- | |
| Submodules: | |
| This module consists of the following submodules: | |
| $(UL | |
| $(LI | |
| The $(MREF std, container, array) module provides | |
| an array type with deterministic control of memory, not reliant on | |
| the GC unlike built-in arrays. | |
| ) | |
| $(LI | |
| The $(MREF std, container, binaryheap) module | |
| provides a binary heap implementation that can be applied to any | |
| user-provided random-access range. | |
| ) | |
| $(LI | |
| The $(MREF std, container, dlist) module provides | |
| a doubly-linked list implementation. | |
| ) | |
| $(LI | |
| The $(MREF std, container, rbtree) module | |
| implements red-black trees. | |
| ) | |
| $(LI | |
| The $(MREF std, container, slist) module | |
| implements singly-linked lists. | |
| ) | |
| $(LI | |
| The $(MREF std, container, util) module contains | |
| some generic tools commonly used by container implementations. | |
| ) | |
| ) | |
| The_primary_range_of_a_container: | |
| While some containers offer direct access to their elements e.g. via | |
| `opIndex`, `c.front` or `c.back`, access | |
| and modification of a container's contents is generally done through | |
| its primary $(MREF_ALTTEXT range, std, range) type, | |
| which is aliased as `C.Range`. For example, the primary range type of | |
| `Array!int` is `Array!int.Range`. | |
| If the documentation of a member function of a container takes | |
| a parameter of type `Range`, then it refers to the primary range type of | |
| this container. Oftentimes `Take!Range` will be used, in which case | |
| the range refers to a span of the elements in the container. Arguments to | |
| these parameters $(B must) be obtained from the same container instance | |
| as the one being worked with. It is important to note that many generic range | |
| algorithms return the same range type as their input range. | |
| --- | |
| import std.algorithm.comparison : equal; | |
| import std.algorithm.iteration : find; | |
| import std.container; | |
| import std.range : take; | |
| auto array = make!Array(1, 2, 3); | |
| // `find` returns an Array!int.Range advanced to the element "2" | |
| array.linearRemove(array[].find(2)); | |
| assert(array[].equal([1])); | |
| array = make!Array(1, 2, 3); | |
| // the range given to `linearRemove` is a Take!(Array!int.Range) | |
| // spanning just the element "2" | |
| array.linearRemove(array[].find(2).take(1)); | |
| assert(array[].equal([1, 3])); | |
| --- | |
| When any $(MREF_ALTTEXT range, std, range) can be passed as an argument to | |
| a member function, the documention usually refers to the parameter's templated | |
| type as `Stuff`. | |
| --- | |
| import std.algorithm.comparison : equal; | |
| import std.container; | |
| import std.range : iota; | |
| auto array = make!Array(1, 2); | |
| // the range type returned by `iota` is completely unrelated to Array, | |
| // which is fine for Array.insertBack: | |
| array.insertBack(iota(3, 10)); | |
| assert(array[].equal([1, 2, 3, 4, 5, 6, 7, 8, 9])); | |
| --- | |
| Container_primitives: | |
| Containers do not form a class hierarchy, instead they implement a | |
| common set of primitives (see table below). These primitives each guarantee | |
| a specific worst case complexity and thus allow generic code to be written | |
| independently of the container implementation. | |
| For example the primitives `c.remove(r)` and `c.linearRemove(r)` both | |
| remove the sequence of elements in range `r` from the container `c`. | |
| The primitive `c.remove(r)` guarantees | |
| $(BIGOH n$(SUBSCRIPT r) log n$(SUBSCRIPT c)) complexity in the worst case and | |
| `c.linearRemove(r)` relaxes this guarantee to $(BIGOH n$(SUBSCRIPT c)). | |
| Since a sequence of elements can be removed from a $(MREF_ALTTEXT doubly linked list,std,container,dlist) | |
| in constant time, `DList` provides the primitive `c.remove(r)` | |
| as well as `c.linearRemove(r)`. On the other hand | |
| $(MREF_ALTTEXT Array, std,container, array) only offers `c.linearRemove(r)`. | |
| The following table describes the common set of primitives that containers | |
| implement. A container need not implement all primitives, but if a | |
| primitive is implemented, it must support the syntax described in the $(B | |
| syntax) column with the semantics described in the $(B description) column, and | |
| it must not have a worst-case complexity worse than denoted in big-O notation in | |
| the $(BIGOH ·) column. Below, `C` means a container type, `c` is | |
| a value of container type, $(D n$(SUBSCRIPT x)) represents the effective length of | |
| value `x`, which could be a single element (in which case $(D n$(SUBSCRIPT x)) is | |
| `1`), a container, or a range. | |
| $(BOOKTABLE Container primitives, | |
| $(TR | |
| $(TH Syntax) | |
| $(TH $(BIGOH ·)) | |
| $(TH Description) | |
| ) | |
| $(TR | |
| $(TDNW `C(x)`) | |
| $(TDNW $(D n$(SUBSCRIPT x))) | |
| $(TD Creates a container of type `C` from either another container or a range. | |
| The created container must not be a null reference even if x is empty.) | |
| ) | |
| $(TR | |
| $(TDNW `c.dup`) | |
| $(TDNW $(D n$(SUBSCRIPT c))) | |
| $(TD Returns a duplicate of the container.) | |
| ) | |
| $(TR | |
| $(TDNW $(D c ~ x)) | |
| $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x))) | |
| $(TD Returns the concatenation of `c` and `r`. `x` may be a single | |
| element or an input range.) | |
| ) | |
| $(TR | |
| $(TDNW $(D x ~ c)) | |
| $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x))) | |
| $(TD Returns the concatenation of `x` and `c`. `x` may be a | |
| single element or an input range type.) | |
| ) | |
| $(LEADINGROWN 3, Iteration | |
| ) | |
| $(TR | |
| $(TD `c.Range`) | |
| $(TD) | |
| $(TD The primary range type associated with the container.) | |
| ) | |
| $(TR | |
| $(TD `c[]`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns a range | |
| iterating over the entire container, in a container-defined order.) | |
| ) | |
| $(TR | |
| $(TDNW $(D c[a .. b])) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Fetches a portion of the container from key `a` to key `b`.) | |
| ) | |
| $(LEADINGROWN 3, Capacity | |
| ) | |
| $(TR | |
| $(TD `c.empty`) | |
| $(TD `1`) | |
| $(TD Returns `true` if the container has no elements, `false` otherwise.) | |
| ) | |
| $(TR | |
| $(TD `c.length`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns the number of elements in the container.) | |
| ) | |
| $(TR | |
| $(TDNW $(D c.length = n)) | |
| $(TDNW $(D n$(SUBSCRIPT c) + n)) | |
| $(TD Forces the number of elements in the container to `n`. | |
| If the container ends up growing, the added elements are initialized | |
| in a container-dependent manner (usually with `T.init`).) | |
| ) | |
| $(TR | |
| $(TD `c.capacity`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns the maximum number of elements that can be stored in the | |
| container without triggering a reallocation.) | |
| ) | |
| $(TR | |
| $(TD `c.reserve(x)`) | |
| $(TD $(D n$(SUBSCRIPT c))) | |
| $(TD Forces `capacity` to at least `x` without reducing it.) | |
| ) | |
| $(LEADINGROWN 3, Access | |
| ) | |
| $(TR | |
| $(TDNW `c.front`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns the first element of the container, in a container-defined order.) | |
| ) | |
| $(TR | |
| $(TDNW `c.moveFront`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Destructively reads and returns the first element of the | |
| container. The slot is not removed from the container; it is left | |
| initialized with `T.init`. This routine need not be defined if $(D | |
| front) returns a `ref`.) | |
| ) | |
| $(TR | |
| $(TDNW $(D c.front = v)) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Assigns `v` to the first element of the container.) | |
| ) | |
| $(TR | |
| $(TDNW `c.back`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns the last element of the container, in a container-defined order.) | |
| ) | |
| $(TR | |
| $(TDNW `c.moveBack`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Destructively reads and returns the last element of the | |
| container. The slot is not removed from the container; it is left | |
| initialized with `T.init`. This routine need not be defined if $(D | |
| front) returns a `ref`.) | |
| ) | |
| $(TR | |
| $(TDNW $(D c.back = v)) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Assigns `v` to the last element of the container.) | |
| ) | |
| $(TR | |
| $(TDNW `c[x]`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Provides indexed access into the container. The index type is | |
| container-defined. A container may define several index types (and | |
| consequently overloaded indexing).) | |
| ) | |
| $(TR | |
| $(TDNW `c.moveAt(x)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Destructively reads and returns the value at position `x`. The slot | |
| is not removed from the container; it is left initialized with $(D | |
| T.init).) | |
| ) | |
| $(TR | |
| $(TDNW $(D c[x] = v)) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Sets element at specified index into the container.) | |
| ) | |
| $(TR | |
| $(TDNW $(D c[x] $(I op)= v)) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Performs read-modify-write operation at specified index into the | |
| container.) | |
| ) | |
| $(LEADINGROWN 3, Operations | |
| ) | |
| $(TR | |
| $(TDNW $(D e in c)) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns nonzero if e is found in `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.lowerBound(v)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns a range of all elements strictly less than `v`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.upperBound(v)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns a range of all elements strictly greater than `v`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.equalRange(v)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Returns a range of all elements in `c` that are equal to `v`.) | |
| ) | |
| $(LEADINGROWN 3, Modifiers | |
| ) | |
| $(TR | |
| $(TDNW $(D c ~= x)) | |
| $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x))) | |
| $(TD Appends `x` to `c`. `x` may be a single element or an input range type.) | |
| ) | |
| $(TR | |
| $(TDNW `c.clear()`) | |
| $(TDNW $(D n$(SUBSCRIPT c))) | |
| $(TD Removes all elements in `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.insert(x)`) | |
| $(TDNW $(D n$(SUBSCRIPT x) * log n$(SUBSCRIPT c))) | |
| $(TD Inserts `x` in `c` at a position (or positions) chosen by `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableInsert(x)`) | |
| $(TDNW $(D n$(SUBSCRIPT x) * log n$(SUBSCRIPT c))) | |
| $(TD Same as `c.insert(x)`, but is guaranteed to not invalidate any ranges.) | |
| ) | |
| $(TR | |
| $(TDNW `c.linearInsert(v)`) | |
| $(TDNW $(D n$(SUBSCRIPT c))) | |
| $(TD Same as `c.insert(v)` but relaxes complexity to linear.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableLinearInsert(v)`) | |
| $(TDNW $(D n$(SUBSCRIPT c))) | |
| $(TD Same as `c.stableInsert(v)` but relaxes complexity to linear.) | |
| ) | |
| $(TR | |
| $(TDNW `c.removeAny()`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Removes some element from `c` and returns it.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableRemoveAny()`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Same as `c.removeAny()`, but is guaranteed to not invalidate any | |
| iterators.) | |
| ) | |
| $(TR | |
| $(TDNW `c.insertFront(v)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Inserts `v` at the front of `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableInsertFront(v)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Same as `c.insertFront(v)`, but guarantees no ranges will be | |
| invalidated.) | |
| ) | |
| $(TR | |
| $(TDNW `c.insertBack(v)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Inserts `v` at the back of `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableInsertBack(v)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Same as `c.insertBack(v)`, but guarantees no ranges will be | |
| invalidated.) | |
| ) | |
| $(TR | |
| $(TDNW `c.removeFront()`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Removes the element at the front of `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableRemoveFront()`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Same as `c.removeFront()`, but guarantees no ranges will be | |
| invalidated.) | |
| ) | |
| $(TR | |
| $(TDNW `c.removeBack()`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Removes the value at the back of `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableRemoveBack()`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Same as `c.removeBack()`, but guarantees no ranges will be | |
| invalidated.) | |
| ) | |
| $(TR | |
| $(TDNW `c.remove(r)`) | |
| $(TDNW $(D n$(SUBSCRIPT r) * log n$(SUBSCRIPT c))) | |
| $(TD Removes range `r` from `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableRemove(r)`) | |
| $(TDNW $(D n$(SUBSCRIPT r) * log n$(SUBSCRIPT c))) | |
| $(TD Same as `c.remove(r)`, but guarantees iterators are not | |
| invalidated.) | |
| ) | |
| $(TR | |
| $(TDNW `c.linearRemove(r)`) | |
| $(TDNW $(D n$(SUBSCRIPT c))) | |
| $(TD Removes range `r` from `c`.) | |
| ) | |
| $(TR | |
| $(TDNW `c.stableLinearRemove(r)`) | |
| $(TDNW $(D n$(SUBSCRIPT c))) | |
| $(TD Same as `c.linearRemove(r)`, but guarantees iterators are not | |
| invalidated.) | |
| ) | |
| $(TR | |
| $(TDNW `c.removeKey(k)`) | |
| $(TDNW $(D log n$(SUBSCRIPT c))) | |
| $(TD Removes an element from `c` by using its key `k`. | |
| The key's type is defined by the container.) | |
| ) | |
| ) | |
| Source: $(PHOBOSSRC std/container/package.d) | |
| Copyright: Red-black tree code copyright (C) 2008- by Steven Schveighoffer. Other code | |
| copyright 2010- Andrei Alexandrescu. All rights reserved by the respective holders. | |
| License: Distributed under the Boost Software License, Version 1.0. | |
| (See accompanying file LICENSE_1_0.txt or copy at $(HTTP | |
| boost.org/LICENSE_1_0.txt)). | |
| Authors: Steven Schveighoffer, $(HTTP erdani.com, Andrei Alexandrescu) | |
| */ | |
| module std.container; | |
| public import std.container.array; | |
| public import std.container.binaryheap; | |
| public import std.container.dlist; | |
| public import std.container.rbtree; | |
| public import std.container.slist; | |
| import std.meta; | |
| /* The following documentation and type `TotalContainer` are | |
| intended for developers only. | |
| `TotalContainer` is an unimplemented container that illustrates a | |
| host of primitives that a container may define. It is to some extent | |
| the bottom of the conceptual container hierarchy. A given container | |
| most often will choose to only implement a subset of these primitives, | |
| and define its own additional ones. Adhering to the standard primitive | |
| names below allows generic code to work independently of containers. | |
| Things to remember: any container must be a reference type, whether | |
| implemented as a `class` or `struct`. No primitive below | |
| requires the container to escape addresses of elements, which means | |
| that compliant containers can be defined to use reference counting or | |
| other deterministic memory management techniques. | |
| A container may choose to define additional specific operations. The | |
| only requirement is that those operations bear different names than | |
| the ones below, lest user code gets confused. | |
| Complexity of operations should be interpreted as "at least as good | |
| as". If an operation is required to have $(BIGOH n) complexity, it | |
| could have anything lower than that, e.g. $(BIGOH log(n)). Unless | |
| specified otherwise, `n` inside a $(BIGOH) expression stands for | |
| the number of elements in the container. | |
| */ | |
| struct TotalContainer(T) | |
| { | |
| /** | |
| If the container has a notion of key-value mapping, `KeyType` | |
| defines the type of the key of the container. | |
| */ | |
| alias KeyType = T; | |
| /** | |
| If the container has a notion of multikey-value mapping, $(D | |
| KeyTypes[k]), where `k` is a zero-based unsigned number, defines | |
| the type of the `k`th key of the container. | |
| A container may define both `KeyType` and `KeyTypes`, e.g. in | |
| the case it has the notion of primary/preferred key. | |
| */ | |
| alias KeyTypes = AliasSeq!T; | |
| /** | |
| If the container has a notion of key-value mapping, `ValueType` | |
| defines the type of the value of the container. Typically, a map-style | |
| container mapping values of type `K` to values of type `V` | |
| defines `KeyType` to be `K` and `ValueType` to be `V`. | |
| */ | |
| alias ValueType = T; | |
| /** | |
| Defines the container's primary range, which embodies one of the | |
| ranges defined in $(MREF std,range). | |
| Generally a container may define several types of ranges. | |
| */ | |
| struct Range | |
| { | |
| /++ | |
| Range primitives. | |
| +/ | |
| @property bool empty() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| @property ref T front() //ref return optional | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| @property void front(T value) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| T moveFront() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| void popFront() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| @property ref T back() //ref return optional | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| @property void back(T value) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| T moveBack() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| void popBack() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| T opIndex(size_t i) //ref return optional | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| void opIndexAssign(size_t i, T value) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| T opIndexUnary(string op)(size_t i) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| void opIndexOpAssign(string op)(size_t i, T value) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| T moveAt(size_t i) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| @property size_t length() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| } | |
| /** | |
| Property returning `true` if and only if the container has no | |
| elements. | |
| Complexity: $(BIGOH 1) | |
| */ | |
| @property bool empty() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns a duplicate of the container. The elements themselves are not | |
| transitively duplicated. | |
| Complexity: $(BIGOH n). | |
| */ | |
| @property TotalContainer dup() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns the number of elements in the container. | |
| Complexity: $(BIGOH log(n)). | |
| */ | |
| @property size_t length() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns the maximum number of elements the container can store without | |
| (a) allocating memory, (b) invalidating iterators upon insertion. | |
| Complexity: $(BIGOH log(n)). | |
| */ | |
| @property size_t capacity() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Ensures sufficient capacity to accommodate `n` elements. | |
| Postcondition: $(D capacity >= n) | |
| Complexity: $(BIGOH log(e - capacity)) if $(D e > capacity), otherwise | |
| $(BIGOH 1). | |
| */ | |
| void reserve(size_t e) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns a range that iterates over all elements of the container, in a | |
| container-defined order. The container should choose the most | |
| convenient and fast method of iteration for `opSlice()`. | |
| Complexity: $(BIGOH log(n)) | |
| */ | |
| Range opSlice() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns a range that iterates the container between two | |
| specified positions. | |
| Complexity: $(BIGOH log(n)) | |
| */ | |
| Range opSlice(size_t a, size_t b) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Forward to `opSlice().front` and `opSlice().back`, respectively. | |
| Complexity: $(BIGOH log(n)) | |
| */ | |
| @property ref T front() //ref return optional | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| @property void front(T value) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| T moveFront() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| @property ref T back() //ref return optional | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| @property void back(T value) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// Ditto | |
| T moveBack() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Indexing operators yield or modify the value at a specified index. | |
| */ | |
| ref T opIndex(KeyType) //ref return optional | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| void opIndexAssign(KeyType i, T value) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| T opIndexUnary(string op)(KeyType i) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| void opIndexOpAssign(string op)(KeyType i, T value) //Only when front does not return by ref | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| T moveAt(KeyType i) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| $(D k in container) returns true if the given key is in the container. | |
| */ | |
| bool opBinaryRight(string op)(KeyType k) | |
| if (op == "in") | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns a range of all elements containing `k` (could be empty or a | |
| singleton range). | |
| */ | |
| Range equalRange(KeyType k) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns a range of all elements with keys less than `k` (could be | |
| empty or a singleton range). Only defined by containers that store | |
| data sorted at all times. | |
| */ | |
| Range lowerBound(KeyType k) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns a range of all elements with keys larger than `k` (could be | |
| empty or a singleton range). Only defined by containers that store | |
| data sorted at all times. | |
| */ | |
| Range upperBound(KeyType k) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Returns a new container that's the concatenation of `this` and its | |
| argument. `opBinaryRight` is only defined if `Stuff` does not | |
| define `opBinary`. | |
| Complexity: $(BIGOH n + m), where m is the number of elements in $(D | |
| stuff) | |
| */ | |
| TotalContainer opBinary(string op)(Stuff rhs) | |
| if (op == "~") | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| TotalContainer opBinaryRight(string op)(Stuff lhs) | |
| if (op == "~") | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Forwards to $(D insertAfter(this[], stuff)). | |
| */ | |
| void opOpAssign(string op)(Stuff stuff) | |
| if (op == "~") | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Removes all contents from the container. The container decides how $(D | |
| capacity) is affected. | |
| Postcondition: `empty` | |
| Complexity: $(BIGOH n) | |
| */ | |
| void clear() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Sets the number of elements in the container to `newSize`. If $(D | |
| newSize) is greater than `length`, the added elements are added to | |
| unspecified positions in the container and initialized with $(D | |
| .init). | |
| Complexity: $(BIGOH abs(n - newLength)) | |
| Postcondition: $(D _length == newLength) | |
| */ | |
| @property void length(size_t newLength) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Inserts `stuff` in an unspecified position in the | |
| container. Implementations should choose whichever insertion means is | |
| the most advantageous for the container, but document the exact | |
| behavior. `stuff` can be a value convertible to the element type of | |
| the container, or a range of values convertible to it. | |
| The `stable` version guarantees that ranges iterating over the | |
| container are never invalidated. Client code that counts on | |
| non-invalidating insertion should use `stableInsert`. Such code would | |
| not compile against containers that don't support it. | |
| Returns: The number of elements added. | |
| Complexity: $(BIGOH m * log(n)), where `m` is the number of | |
| elements in `stuff` | |
| */ | |
| size_t insert(Stuff)(Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| ///ditto | |
| size_t stableInsert(Stuff)(Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Same as `insert(stuff)` and `stableInsert(stuff)` respectively, | |
| but relax the complexity constraint to linear. | |
| */ | |
| size_t linearInsert(Stuff)(Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| ///ditto | |
| size_t stableLinearInsert(Stuff)(Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Picks one value in an unspecified position in the container, removes | |
| it from the container, and returns it. Implementations should pick the | |
| value that's the most advantageous for the container. The stable version | |
| behaves the same, but guarantees that ranges iterating over the container | |
| are never invalidated. | |
| Precondition: `!empty` | |
| Returns: The element removed. | |
| Complexity: $(BIGOH log(n)). | |
| */ | |
| T removeAny() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| T stableRemoveAny() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Inserts `value` to the front or back of the container. `stuff` | |
| can be a value convertible to the container's element type or a range | |
| of values convertible to it. The stable version behaves the same, but | |
| guarantees that ranges iterating over the container are never | |
| invalidated. | |
| Returns: The number of elements inserted | |
| Complexity: $(BIGOH log(n)). | |
| */ | |
| size_t insertFront(Stuff)(Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t stableInsertFront(Stuff)(Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t insertBack(Stuff)(Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t stableInsertBack(T value) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Removes the value at the front or back of the container. The stable | |
| version behaves the same, but guarantees that ranges iterating over | |
| the container are never invalidated. The optional parameter $(D | |
| howMany) instructs removal of that many elements. If $(D howMany > n), | |
| all elements are removed and no exception is thrown. | |
| Precondition: `!empty` | |
| Complexity: $(BIGOH log(n)). | |
| */ | |
| void removeFront() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| void stableRemoveFront() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| void removeBack() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| void stableRemoveBack() | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Removes `howMany` values at the front or back of the | |
| container. Unlike the unparameterized versions above, these functions | |
| do not throw if they could not remove `howMany` elements. Instead, | |
| if $(D howMany > n), all elements are removed. The returned value is | |
| the effective number of elements removed. The stable version behaves | |
| the same, but guarantees that ranges iterating over the container are | |
| never invalidated. | |
| Returns: The number of elements removed | |
| Complexity: $(BIGOH howMany * log(n)). | |
| */ | |
| size_t removeFront(size_t howMany) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t stableRemoveFront(size_t howMany) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t removeBack(size_t howMany) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t stableRemoveBack(size_t howMany) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Removes all values corresponding to key `k`. | |
| Complexity: $(BIGOH m * log(n)), where `m` is the number of | |
| elements with the same key. | |
| Returns: The number of elements removed. | |
| */ | |
| size_t removeKey(KeyType k) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Inserts `stuff` before, after, or instead range `r`, which must | |
| be a valid range previously extracted from this container. `stuff` | |
| can be a value convertible to the container's element type or a range | |
| of objects convertible to it. The stable version behaves the same, but | |
| guarantees that ranges iterating over the container are never | |
| invalidated. | |
| Returns: The number of values inserted. | |
| Complexity: $(BIGOH n + m), where `m` is the length of `stuff` | |
| */ | |
| size_t insertBefore(Stuff)(Range r, Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t stableInsertBefore(Stuff)(Range r, Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t insertAfter(Stuff)(Range r, Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t stableInsertAfter(Stuff)(Range r, Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t replace(Stuff)(Range r, Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| size_t stableReplace(Stuff)(Range r, Stuff stuff) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Removes all elements belonging to `r`, which must be a range | |
| obtained originally from this container. The stable version behaves the | |
| same, but guarantees that ranges iterating over the container are | |
| never invalidated. | |
| Returns: A range spanning the remaining elements in the container that | |
| initially were right after `r`. | |
| Complexity: $(BIGOH m * log(n)), where `m` is the number of | |
| elements in `r` | |
| */ | |
| Range remove(Range r) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| Range stableRemove(Range r) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /** | |
| Same as `remove` above, but has complexity relaxed to linear. | |
| Returns: A range spanning the remaining elements in the container that | |
| initially were right after `r`. | |
| Complexity: $(BIGOH n) | |
| */ | |
| Range linearRemove(Range r) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| /// ditto | |
| Range stableLinearRemove(Range r) | |
| { | |
| assert(0, "Not implemented"); | |
| } | |
| } | |
| @safe unittest | |
| { | |
| TotalContainer!int test; | |
| } |