Constraints

"İbrahim Gökhan "İbrahim Gökhan
Wed May 9 08:03:40 PDT 2012


// SAMPLE CONSTRAINTS
//=============================================================

constraint CInputRange
{
	static assert (is(typeof(
	{
		typeof(this) r = void;
		if (r.empty) {}
		r.popFront();
		auto h = r.front;
	})));
}

constraint CForwardRange : CInputRange
{
	static assert (is(typeof(
	{
		typeof(this) r1 = void;
		typeof(this) r2 = r1.save;
	})));
}

constraint CBidirectionalRange : CForwardRange
{
	static assert (is(typeof(
	{
		typeof(this) r = void;
		r.popBack();
		auto t = r.back;
		auto w = r.front;
		static assert(is(typeof(t) == typeof(w)));
	})));
}

constraint CRandomAccessRange : CBidirectionalRange
	if (!isInfinite!typeof(this))
{
	static assert (is(typeof(
	{
		typeof(this) r = void;
		auto e = r[1];
	})));
	static assert(hasLength!typeof(this));
     static assert(!isNarrowString!typeof(this));
}

constraint CRandomAccessRange : CForwardRange
	if (isInfinite!typeof(this))
{
	static assert (is(typeof(
	{
		typeof(this) r = void;
		auto e = r[1];
	})));
}

// SAMPLE USAGES
//=========================================================

struct InputRange : CInputRange // Apply constraint to a struct
{
	....
}

struct ForwardRange // Do not apply any constraint but implement 
a ForwardRange
{
	....
}

interface IBidirectionalRange : CBidirectionalRange // Apply 
constraint to the classes derived from IBidirectionalRange
{
	....
}

class BidirectionalRange : IBidirectionalRange  // Implement 
BidirectionalRange and apply constraint CBidirectionalRange
{
	...
}

struct RandomAccessFinite : CRandomAccessRange
{
	...
}

struct RandomAccessInfinite : CRandomAccessRange
{
	...
}

//-----------------------------------------------------------

void foo(Range : CInputRange)(Range r) { }         // (1)
void foo(Range : CForwardRange)(Range r) { }       // (2)
void foo(Range : CBidirectionalRange)(Range r) { } // (3)
void foo(Range : CRandomAccessRange)(Range r) { }  // (4)

//-----------------------------------------------------------

void main()
{
	InputRange ir;
	ForwardRange fr;
	auto br = new BidirectionalRange();
	RandomAccessFinite rfr;
	RandomAccessInfinite rir;
	
	foo(ir);  // calls (1)
	foo(fr);  // calls (2)
	foo(br);  // calls (3)
	foo(rfr); // calls (4)
	foo(rir); // calls (4)
}



More information about the Digitalmars-d mailing list