Constraints
"İbrahim Gökhan
"İbrahim Gökhan
Thu May 10 02:44:29 PDT 2012
//====================================================
//== OR ===
//====================================================
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
{
R r = void; // 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
}));
}
template isJustInputRange(R)
{
enum bool isJustInputRange = isInputRange!R &&
!isForwardRange!R;
}
template isForwardRange(R)
{
enum bool isForwardRange = isInputRange!R && is(typeof(
{
R r1 = void;
R r2 = r1.save; // can call "save" against a range object
}));
}
template isJustForwardRange(R)
{
enum bool isJustForwardRange = isForwardRange!R &&
!isBidirectionalRange!R && !isRandomAccessRange!R;
}
template isBidirectionalRange(R)
{
enum bool isBidirectionalRange = isForwardRange!R &&
is(typeof(
{
R r = void;
r.popBack();
auto t = r.back;
auto w = r.front;
static assert(is(typeof(t) == typeof(w)));
}));
}
template isJustBidirectionalRange(R)
{
enum bool isJustBidirectionalRange = isBidirectionalRange!R
&& !isRandomAccessRange!R;
}
template isRandomAccessRange(R)
{
enum bool isRandomAccessRange = is(typeof(
{
static assert(isBidirectionalRange!R ||
isForwardRange!R && isInfinite!R);
R r = void;
auto e = r[1];
static assert(!isNarrowString!R);
static assert(hasLength!R || isInfinite!R);
}));
}
//-----------------------------------------------------------
struct InputRange
{
....
static assert (isInputRange!InputRange);
}
struct ForwardRange
{
....
static assert (isForwardRange!ForwardRange);
}
interface IBidirectionalRange
{
....
// static assert (isBidirectionalRange!IBidirectionalRange);
// can not be used in interfaces
}
class BidirectionalRange : IBidirectionalRange
{
...
static assert (isBidirectionalRange!BidirectionalRange);
}
struct RandomAccessFinite
{
...
static assert (isRandomAccessRange!RandomAccessFinite);
}
struct RandomAccessInfinite
{
...
static assert (isRandomAccessRange!RandomAccessInfinite);
}
//-----------------------------------------------------------
void foo(Range)(Range r) if (isJustInputRange!Range) { }
void foo(Range)(Range r) if (isJustForwardRange!Range) { }
void foo(Range)(Range r) if (isJustBidirectionalRange!Range) { }
void foo(Range)(Range r) if (isRandomAccessRange!Range) { }
More information about the Digitalmars-d
mailing list