Module std.range
This module defines the notion of a range. Ranges generalize the concept of arrays, lists, or anything that involves sequential access. This abstraction enables the same set of algorithms (see std.algorithm) to be used with a vast variety of different concrete types. For example, a linear search algorithm such as std.algorithm.find works not just for arrays, but for linked-lists, input files, incoming network data, etc.
For more detailed information about the conceptual aspect of ranges and the motivation behind them, see Andrei Alexandrescu's article On Iteration.
Submodules
This module has two submodules:
The std.range.primitives
submodule
provides basic range functionality. It defines several templates for testing
whether a given object
is a range, what kind of range it is, and provides
some common range operations.
The std.range.interfaces
submodule
provides object
-based interfaces for working with ranges via runtime
polymorphism.
The remainder of this module provides a rich set of range creation and composition templates that let you construct new ranges out of existing ranges:
|
Concatenates several ranges into a single range. |
|
Chooses one of two ranges at runtime based on a boolean condition. |
|
Chooses one of several ranges at runtime based on an index. |
|
Creates a range that returns fixed-size chunks of the original
range.
|
|
Creates an infinite range that repeats the given forward range indefinitely. Good for implementing circular buffers. |
|
Creates the range that results from discarding the first n elements from the given range. |
|
Creates the range that results from discarding exactly n of the first elements from the given range. |
|
Creates the range that results from discarding the first elements from the given range. |
|
Iterates a range with an attached index variable. |
|
Creates a range that iterates over the first elements of the given ranges. |
|
Creates a range that offers a view of a given range as though its elements were reordered according to a given range of indices. |
|
Creates a range consisting of numbers between a starting point and ending pointspaced apart by a given interval. |
|
Iterates n ranges in lockstep , for use in a foreach
loop. Similar to , except that is designed
especially for foreach loops.
|
|
An output range that discards the data it receives. |
|
Creates a range that iterates over the given arguments. |
|
Given a random-access range and a starting point, creates a range that alternately returns the next left and next right element to the starting point. |
|
Creates a forward range whose values are defined by a
mathematical recurrence relation.
|
|
Creates a range that consists of a single element repeated n times, or an infinite range repeating that element indefinitely. |
|
Iterates a bidirectional range backwards. |
|
Given n ranges, creates a new range that return the n first elements of each range, in turn, then the second element of each range, and so on, in a round-robin fashion. |
|
Similar to , except that a random-access range is
created.
|
|
Iterates a range with stride n.
|
|
Creates a sub-range consisting of only up to the first n
elements of the given range.
|
|
Like , but assumes the given range actually has n
elements, and therefore also defines the length property.
|
|
Creates a random-access range consisting of zero elements of the given range. |
|
Creates a random-access range consisting of exactly the first element of the given range. |
|
Creates a range that wraps a given range, forwarding along its elements while also calling a provided function with each element. |
|
Transposes a range of ranges. |
|
Creates a range that iterates over the n'th elements of the given random-access ranges. |
|
Given n ranges, creates a range that successively returns a tuple of all the first elements, a tuple of all the second elements, etc. |
Ranges whose elements are sorted afford better efficiency with certain
operations. For this, the
function can be used to
construct a assumeSorted
from a pre-sorted range. The SortedRange
std.algorithm.sort
function also conveniently
returns a
. SortedRange
objects provide some additional
range operations that SortedRange
take
advantage of the fact that the range is sorted.
Functions
Name | Description |
---|---|
assumeSorted
|
Assumes is sorted by predicate pred and returns the
corresponding having as support. To
keep the checking costs low, the cost is Ο(1 ) in release mode
(no checks for sortedness are performed). In debug mode, a few random
elements of are checked for sortedness. The size of the sample
is proportional Ο(log(r.length) ). That way, checking has no
effect on the complexity of subsequent operations specific to sorted
ranges (such as binary search). The probability of an arbitrary
unsorted range failing the test is very high (however, an
almost-sorted range is likely to pass it). To check for sortedness at
cost Ο(n ), use std.algorithm.sorting.isSorted .
|
chain
|
Spans multiple ranges in sequence . The function takes any
number of ranges and returns a Chain!(R1, R2,...) object . The
ranges may be different, but they must have the same element type. The
result is a range that offers the front , popFront , and empty primitives. If all input ranges offer random access and length , Chain offers them as well.
|
choose
|
Choose one of two ranges at runtime depending on a Boolean condition .
|
chooseAmong
|
Choose one of multiple ranges at runtime. |
chunks
|
This range iterates over fixed-sized chunks of size of a
range. Source must be a forward range.
|
cycle
|
Repeats the given forward range ad infinitum. If the original range is
infinite (fact that would make the identity application),
detects that and aliases itself to the range type
itself. If the original range has random access, offers
random access and also offers a constructor taking an initial position
. works with static arrays in addition to ranges,
mostly for performance reasons.
|
drop
|
Convenience function which calls
range.popFrontN( and returns .
makes it easier to pop elements from a range
and then pass it to another function within a single expression,
whereas popFrontN would require multiple statements.
|
dropBack
|
Convenience function which calls
range.popFrontN( and returns .
makes it easier to pop elements from a range
and then pass it to another function within a single expression,
whereas popFrontN would require multiple statements.
|
dropBackExactly
|
Similar to drop and but they call
range.popFrontExactly( and range.popBackExactly(
instead.
|
dropBackOne
|
Convenience function which calls
range.popFront() and returns .
makes it easier to pop an element from a range
and then pass it to another function within a single expression,
whereas popFront would require multiple statements.
|
dropExactly
|
Similar to drop and but they call
range.popFrontExactly( and range.popBackExactly(
instead.
|
dropOne
|
Convenience function which calls
range.popFront() and returns .
makes it easier to pop an element from a range
and then pass it to another function within a single expression,
whereas popFront would require multiple statements.
|
enumerate
|
Iterate over with an attached index variable.
|
frontTransversal
|
Given a range of ranges, iterate transversally through the first elements of each of the enclosed ranges. |
generate
|
Given callable (std.traits.isCallable ) , create as a range
whose front is defined by successive calls to .
This is especially useful to call function with global side effects (random
functions), or to create ranges expressed as a single delegate, rather than
an entire front /popFront /empty structure.
maybe be passed either a template alias parameter (existing
function, delegate, struct type defining static opCall ... ) or
a run-time value argument (delegate, function object ... ).
The result range models an InputRange
(std.range.primitives.isInputRange ).
The resulting range will call on every call to front ,
and only when front is called, regardless of how the range is
iterated.
It is advised to compose generate with either
std.algorithm.iteration.cache or std.array.array , or to use it in a
foreach loop.
A by-value foreach loop means that the loop value is not ref .
|
indexed
|
This struct takes two ranges, and , and creates a view
of as if its elements were reordered according to .
may include only a subset of the elements of and
may also repeat elements.
|
iota
|
Construct a range of values that span the given starting and stopping values. |
lockstep
|
Iterate multiple ranges in lockstep using a foreach loop. If only a single
range is passed in, the aliases itself away. If the
ranges are of different lengths and ==
stop after the shortest range is empty. If the ranges are of different
lengths and == , throw an
exception. may not be , and passing this
will throw an exception.
|
only
|
Assemble into a range that carries all its
elements in-situ.
|
radial
|
Iterates a random-access range starting from a given point and progressively extending left and right from that point. If no initial point is given, iteration starts from the middle of the range. Iteration spans the entire range. |
recurrence
|
Creates a mathematical sequence given the initial values and a
recurrence function that computes the next value from the existing
values. The sequence comes in the form of an infinite forward
range. The type itself is seldom used directly; most
often, recurrences are obtained by calling the function .
|
refRange
|
Helper function for constructing a RefRange .
|
repeat
|
Repeats one value forever.
|
repeat
|
Repeats exactly times. Equivalent to .
|
retro
|
Iterates a bidirectional range backwards. The original range can be
accessed by using the source property. Applying retro twice to
the same range yields the original range.
|
roundRobin
|
yields r1.front , then r2.front ,
then r3.front , after which it pops off one element from each and
continues again from r1 . For example, if two ranges are involved,
it alternately yields elements off the two ranges.
stops after it has consumed all ranges (skipping over the ones that
finish early).
|
sequence
|
is similar to except that iteration is
presented in the so-called
closed form. This means that the n th element in the series is
computable directly from the initial values and n itself. This
implies that the interface offered by is a random-access
range, as opposed to the regular , which only offers
forward iteration.
|
stride
|
Iterates range with stride . If the range is a
random-access range, moves by indexing into the range; otherwise,
moves by successive calls to popFront . Applying stride twice to
the same range results in a stride with a step that is the
product of the two applications. It is an error for to be 0.
|
take
|
Lazily takes only up to elements of a range. This is
particularly useful when using with infinite ranges. If the range
offers random access and length , offers them as well.
|
takeExactly
|
Similar to take , but assumes that has at least elements. Consequently, the result of
always defines the length property (and initializes it to )
even when itself does not define length .
|
takeNone
|
Creates an empty range from the given range in Ο(1 ). If it can, it
will return the same range type. If not, it will return
.
|
takeNone
|
Returns an empty range which is statically known to be empty and is
guaranteed to have length and be random access regardless of R 's
capabilities.
|
takeOne
|
Returns a range with at most one element; for example, returns a range consisting of the integer 42 . Calling popFront() off that range renders it empty.
|
tee
|
Implements a "tee " style pipe, wrapping an input range so that elements of the
range can be passed to a provided function or OutputRange as they are
iterated over. This is useful for printing out intermediate values in a long
chain of range code, performing some operation with side-effects on each call
to front or popFront , or diverting the elements of a range into an
auxiliary OutputRange.
|
transposed
|
Given a range of ranges, returns a range of ranges where the i'th subrange contains the i'th elements of the original subranges. |
transversal
|
Given a range of ranges, iterate transversally through the the th element of each of the enclosed ranges. All elements of the
enclosing range must offer random access.
|
zip
|
Iterate several ranges in lockstep . The element type is a proxy tuple
that allows accessing the current element in the n th range by
using e[n] .
offers the lowest range facilities of all components, e.g. it
offers random access iff all ranges offer random access, and also
offers mutation and swapping if all ranges offer it. Due to this, is extremely powerful because it allows manipulating several
ranges in lockstep . For example, the following code sorts two arrays
in parallel:
|
Structs
Name | Description |
---|---|
Chunks
|
This range iterates over fixed-sized chunks of size chunkSize of a
source range. Source must be a forward range.
|
Cycle
|
Repeats the given forward range ad infinitum. If the original range is
infinite (fact that would make the identity application),
detects that and aliases itself to the range type
itself. If the original range has random access, offers
random access and also offers a constructor taking an initial position
index . works with static arrays in addition to ranges,
mostly for performance reasons.
|
FrontTransversal
|
Given a range of ranges, iterate transversally through the first elements of each of the enclosed ranges. |
Indexed
|
This struct takes two ranges, and , and creates a view
of as if its elements were reordered according to .
may include only a subset of the elements of and
may also repeat elements.
|
Lockstep
|
Iterate multiple ranges in lockstep using a foreach loop. If only a single
range is passed in, the aliases itself away. If the
ranges are of different lengths and s ==
stop after the shortest range is empty. If the ranges are of different
lengths and s == , throw an
exception. s may not be , and passing this
will throw an exception.
|
NullSink
|
An OutputRange that discards the data it receives. |
Recurrence
|
Creates a mathematical sequence given the initial values and a
recurrence function that computes the next value from the existing
values. The sequence comes in the form of an infinite forward
range. The type itself is seldom used directly; most
often, recurrences are obtained by calling the function .
|
RefRange
|
Wrapper which effectively makes it possible to pass a range by reference.
Both the original range and the RefRange will always have the exact same
elements. Any operation done on one will affect the other. So, for instance,
if it's passed to a function which would implicitly copy the original range
if it were passed to it, the original range is not copied but is
consumed as if it were a reference type.
|
Repeat
|
Repeats one value forever. |
Sequence
|
is similar to except that iteration is
presented in the so-called
closed form. This means that the n th element in the series is
computable directly from the initial values and n itself. This
implies that the interface offered by is a random-access
range, as opposed to the regular , which only offers
forward iteration.
|
SortedRange
|
Represents a sorted range. In addition to the regular range
primitives, supports additional operations that take advantage of the
ordering, such as merge and binary search. To obtain a from an unsorted range r , use
std.algorithm.sorting.sort which sorts r in place and returns the
corresponding . To construct a from a range
r that is known to be already sorted, use assumeSorted described
below.
|
Take
|
Lazily takes only up to n elements of a range. This is
particularly useful when using with infinite ranges. If the range
offers random access and length , offers them as well.
|
Transversal
|
Given a range of ranges, iterate transversally through the the n th element of each of the enclosed ranges. All elements of the
enclosing range must offer random access.
|
Zip
|
Iterate several ranges in lockstep . The element type is a proxy tuple
that allows accessing the current element in the n th range by
using e[n] .
offers the lowest range facilities of all components, e.g. it
offers random access iff all ranges offer random access, and also
offers mutation and swapping if all ranges offer it. Due to this, is extremely powerful because it allows manipulating several
ranges in lockstep . For example, the following code sorts two arrays
in parallel:
|
Enums
Name | Description |
---|---|
SearchPolicy
|
Policy used with the searching primitives lowerBound , upperBound , and equalRange of SortedRange below.
|
StoppingPolicy
|
Dictates how iteration in a should stop. By default stop at
the end of the shortest of all ranges.
|
TransverseOptions
|
Options for the FrontTransversal and Transversal ranges
(below).
|
Enum values
Name | Type | Description |
---|---|---|
isTwoWayCompatible
|
Returns true if fn accepts variables of type T1 and T2 in any order.
The following code should compile:
|
Authors
Andrei Alexandrescu, David Simcha, and Jonathan M Davis. Credit for some of the ideas in building this module goes to Leonardo Maffi.