View source code Display the source code in std/range/primitives.d from which this page was generated on github. 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 local clone. Page wiki View or edit the community-maintained wiki page associated with this page.

Module std.range.primitives

This module is a submodule of std.range.

It provides basic range functionality by defining several templates for testing whether a given object is a range, and what kind of range it is:

isInputRange Tests if something is an input rangedefined to be something from which one can sequentially read data using the primitives front, popFront, and empty.
isOutputRange Tests if something is an output range, defined to be something to which one can sequentially write data using the put primitive.
isForwardRange Tests if something is a forward range, defined to be an input range with the additional capability that one can save one's current position with the save primitive, thus allowing one to iterate over the same range multiple times.
isBidirectionalRange Tests if something is a bidirectional range, that is, a forward range that allows reverse traversal using the primitives back and popBack.
isRandomAccessRange Tests if something is a random access range, which is a bidirectional range that also supports the array subscripting operation via the primitive opIndex.

It also provides number of templates that test for various range capabilities:

hasMobileElements Tests if a given range's elements can be moved around using the primitives moveFrontmoveBack, or moveAt.
ElementType Returns the element type of a given range.
ElementEncodingType Returns the encoding element type of a given range.
hasSwappableElements Tests if a range is a forward range with swappable elements.
hasAssignableElements Tests if a range is a forward range with mutable elements.
hasLvalueElements Tests if a range is a forward range with elements that can be passed by reference and have their address taken.
hasLength Tests if a given range has the length attribute.
isInfinite Tests if a given range is an infinite range.
hasSlicing Tests if a given range supports the array slicing operation R[x..y].

Finally, it includes some convenience functions for manipulating ranges:

popFrontN Advances a given range by up to n elements.
popBackN Advances a given bidirectional range from the right by up to n elements.
popFrontExactly Advances a given range by up exactly n elements.
popBackExactly Advances a given bidirectional range from the right by exactly n elements.
moveFront Removes the front element of a range.
moveBack Removes the back element of a bidirectional range.
moveAt Removes the i'th element of a random-access range.
walkLength Computes the length of any range in O(n) time.

Functions

Name Description
back Implements the range interface primitive back for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.back is equivalent to back(array). For narrow strings, back automatically returns the last code point as a dchar.
empty Implements the range interface primitive empty for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.empty is equivalent to empty(array).
front Implements the range interface primitive front for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.front is equivalent to front(array). For narrow strings, front automatically returns the first code point as a dchar.
moveAt Moves element at index i of r out and returns it. Leaves r.front in a destroyable state that does not allocate any resources (usually equal to its .init value).
moveBack Moves the back of r out and returns it. Leaves r.back in a destroyable state that does not allocate any resources (usually equal to its .init value).
moveFront Moves the front of r out and returns it. Leaves r.front in a destroyable state that does not allocate any resources (usually equal to its .init value).
popBack Implements the range interface primitive popBack for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.popBack is equivalent to popBack(array). For narrow strings, popFront automatically eliminates the last code point.
popBackExactly Eagerly advances r itself (not a copy) exactly n times (by calling r.popFront). popFrontExactly takes r by ref, so it mutates the original range. Completes in Ο(1) steps for ranges that support slicing, and have either length or are infinite. Completes in Ο(n) time for all other ranges.
popBackN Eagerly advances r itself (not a copy) up to n times (by calling r.popFront). popFrontN takes r by ref, so it mutates the original range. Completes in Ο(1) steps for ranges that support slicing and have length. Completes in Ο(n) time for all other ranges.
popFront Implements the range interface primitive popFront for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.popFront is equivalent to popFront(array). For narrow strings, popFront automatically advances to the next code point.
popFrontExactly Eagerly advances r itself (not a copy) exactly n times (by calling r.popFront). popFrontExactly takes r by ref, so it mutates the original range. Completes in Ο(1) steps for ranges that support slicing, and have either length or are infinite. Completes in Ο(n) time for all other ranges.
popFrontN Eagerly advances r itself (not a copy) up to n times (by calling r.popFront). popFrontN takes r by ref, so it mutates the original range. Completes in Ο(1) steps for ranges that support slicing and have length. Completes in Ο(n) time for all other ranges.
put Outputs e to r. The exact effect is dependent upon the two types. Several cases are accepted, as described below. The code snippets are attempted in order, and the first to compile "wins" and gets evaluated.
save Implements the range interface primitive save for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.save is equivalent to save(array). The function does not duplicate the content of the array, it simply returns its argument.
walkLength This is a best-effort implementation of length for any kind of range.

Templates

Name Description
ElementEncodingType The encoding element type of R. For narrow strings (char[], wchar[] and their qualified variants including string and wstring), ElementEncodingType is the character type of the string. For all other types, ElementEncodingType is the same as ElementType.
ElementType The element type of R. R does not have to be a range. The element type is determined as the type yielded by r.front for an object r of type R. For example, ElementType!(T[]) is T if T[] isn't a narrow string; if it is, the element type is dchar. If R doesn't have front, ElementType!R is void.
isInfinite Returns true if R is an infinite input range. An infinite input range is an input range that has a statically-defined enumerated member called empty that is always false, for example:

Enum values

Name Type Description
hasAssignableElements Returns true if R is an input range and has mutable elements. The following code should compile for any range with assignable elements.
hasLength Returns true if R has a length member that returns an integral type. R does not have to be a range. Note that length is an optional primitive as no range must implement it. Some ranges do not store their length explicitly, some cannot compute it without actually exhausting the range (e.g. socket streams), and some other ranges may be infinite.
hasLvalueElements Tests whether the range R has lvalue elements. These are defined as elements that can be passed by reference and have their address taken. The following code should compile for any range with lvalue elements.
hasMobileElements Returns true iff R is an input range that supports the moveFront primitive, as well as moveBack and moveAt if it's a bidirectional or random access range. These may be explicitly implemented, or may work via the default behavior of the module level functions moveFront and friends. The following code should compile for any range with mobile elements.
hasSlicing Returns true if R offers a slicing operator with integral boundaries that returns a forward range type.
hasSwappableElements Returns true if R is an input range and has swappable elements. The following code should compile for any range with swappable elements.
isBidirectionalRange Returns true if R is a bidirectional range. A bidirectional range is a forward range that also offers the primitives back and popBack. The following code should compile for any bidirectional range.
isForwardRange Returns true if R is a forward range. A forward range is an input range r that can save "checkpoints" by saving r.save to another value of type R. Notable examples of input ranges that are not forward ranges are file/socket ranges; copying such a range will not save the position in the stream, and they most likely reuse an internal buffer as the entire stream does not sit in memory. Subsequently, advancing either the original or the copy will advance the stream, so the copies are not independent.
isInputRange Returns true if R is an input range. An input range must define the primitives empty, popFront, and front. The following code should compile for any input range.
isOutputRange Returns true if R is an output range for elements of type E. An output range is defined functionally as a range that supports the operation put(r, e) as defined above.
isRandomAccessRange Returns true if R is a random-access range. A random-access range is a bidirectional range that also offers the primitive opIndex, OR an infinite forward range that offers opIndex. In either case, the range must either offer length or be infinite. The following code should compile for any random-access range.

Authors

Andrei Alexandrescu, David Simcha, and Jonathan M Davis. Credit for some of the ideas in building this module goes to Leonardo Maffi.

License

Boost License 1.0.

Comments