Enum member std.range.primitives.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.
enum isInputRange(R)
= is(typeof(R .init) == R) && is(ReturnType!((R r) => r .empty) == bool) && is(typeof((return ref R r) => r .front)) && !is(ReturnType!((R r) => r .front) == void) && is(typeof((R r) => r .popFront));
R r; // can define a range object
if (r .empty) {} // can test for empty
r .popFront(); // can invoke popFront()
auto h = r .front; // can get the front of the range of non-void type
The following are rules of input ranges are assumed to hold true in all Phobos code. These rules are not checkable at compile-time, so not conforming to these rules when writing ranges or range based code will result in undefined behavior.
rreturns.empty falseif and only if there is more data available in the range.revaluated multiple times, without calling.empty r, or otherwise mutating the range object or the underlying data, yields the same result for every evaluation..popFront rreturns the current element in the range. It may return by value or by reference..front rcan be legally evaluated if and only if evaluating.front rhas, or would have, equaled.empty false.revaluated multiple times, without calling.front r, or otherwise mutating the range object or the underlying data, yields the same result for every evaluation..popFront radvances to the next element in the range..popFront rcan be called if and only if evaluating.popFront rhas, or would have, equaled.empty false.
Also, note that Phobos code assumes that the primitives r and
r are Ο(1) time complexity wise or "cheap" in terms of
running time. Ο() statements in the documentation of range functions
are made with this assumption.
See Also
The header of std for tutorials on ranges.
Parameters
| Name | Description |
|---|---|
| R | type to be tested |
Returns
true if R is an input range, false if not
Example
struct A {}
struct B
{
void popFront();
@property bool empty();
@property int front();
}
static assert(!isInputRange!A);
static assert( isInputRange!B);
static assert( isInputRange!(int[]));
static assert( isInputRange!(char[]));
static assert(!isInputRange!(char[4]));
static assert( isInputRange!(inout(int)[]));
static struct NotDefaultConstructible
{
@disable this();
void popFront();
@property bool empty();
@property int front();
}
static assert( isInputRange!NotDefaultConstructible);
static struct NotDefaultConstructibleOrCopyable
{
@disable this();
@disable this(this);
void popFront();
@property bool empty();
@property int front();
}
static assert(isInputRange!NotDefaultConstructibleOrCopyable);
static struct Frontless
{
void popFront();
@property bool empty();
}
static assert(!isInputRange!Frontless);
static struct VoidFront
{
void popFront();
@property bool empty();
void front();
}
static assert(!isInputRange!VoidFront);
Authors
Andrei Alexandrescu, David Simcha, and Jonathan M Davis. Credit for some of the ideas in building this module goes to Leonardo Maffi.