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.
r
returns.empty false
if and only if there is more data available in the range.r
evaluated multiple times, without calling.empty r
, or otherwise mutating the range object or the underlying data, yields the same result for every evaluation..popFront r
returns the current element in the range. It may return by value or by reference..front r
can be legally evaluated if and only if evaluating.front r
has, or would have, equaled.empty false
.r
evaluated multiple times, without calling.front r
, or otherwise mutating the range object or the underlying data, yields the same result for every evaluation..popFront r
advances to the next element in the range..popFront r
can be called if and only if evaluating.popFront r
has, 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.