Enum member std.range.primitives.isForwardRange
Returns true
if R
is a forward range. A forward range is an
input range r
that can save "checkpoints" by saving r
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.
enum isForwardRange(R)
= isInputRange!R && is(typeof((R r)
{
return r .save;
}
(R .init)) == R);
The following code should compile for any forward range.
static assert(isInputRange!R);
R r1;
auto s1 = r1 .save;
static assert(is(typeof(s1) == R));
Saving a range is not duplicating it; in the example above, r1
and r2
still refer to the same underlying data. They just
navigate that data independently.
The semantics of a forward range (not checkable during compilation)
are the same as for an input range, with the additional requirement
that backtracking must be possible by saving a copy of the range
object with save
and using it later.
save
behaves in many ways like a copy constructor, and its
implementation typically is done using copy construction.
The existence of a copy constructor, however, does not imply
the range is a forward range. For example, a range that reads
from a TTY consumes its input and cannot save its place and
read it again, and so cannot be a forward range and cannot
have a save
function.
See Also
The header of std
for tutorials on ranges.
Example
static assert(!isForwardRange!(int));
static assert( isForwardRange!(int[]));
static assert( isForwardRange!(inout(int)[]));
Authors
Andrei Alexandrescu, David Simcha, and Jonathan M Davis. Credit for some of the ideas in building this module goes to Leonardo Maffi.