Enum std.range.primitives.member 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.
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
and using it later.
save
Declaration
enum isForwardRange(R) = isInputRange!R && is(typeof((inout int = 0) { R r1 = R.init; auto s1 = r1.save; static assert(is(typeof(s1) == R)); } ));
Example
static assert(!isForwardRange!(int)); static assert( isForwardRange!(int[])); static assert( isForwardRange!(inout(int)[])); // BUG 14544 struct R14544 { int front() { return 0;} void popFront() {} bool empty() { return false; } R14544 save() {return this;} } static assert( isForwardRange!R14544 );
Authors
Andrei Alexandrescu, David Simcha, and Jonathan M Davis. Credit for some of the ideas in building this module goes to Leonardo Maffi.