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