View mode: basic / threaded / horizontal-split · Log in · Help
May 09, 2012
Constraints
// 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)
}
May 09, 2012
Re: Constraints
// implement foo's without constraints
//------------------------------------------------------------

void foo(Range)(Range r)
	if (isInputRange!Range && !isForwardRange!Range)
{ }

void foo(Range)(Range r)
	if (isForwardRange!Range && !isBidirectionalRange!Range &&
!isRandomAccessRange!Range)
{ }

void foo(Range)(Range r)
	if (isBidirectionalRange!Range && !isRandomAccessRange!Range)
{ }

void foo(Range)(Range r)
	if (isRandomAccessRange!Range)
{ }
May 09, 2012
Re: Constraints
Idea is simple: we need same constraints on "implementation" and 
"argument deduction. Syntax may change.
May 09, 2012
Re: Constraints
Sorry I mean "template specialization" instead of "argument 
deduction".
May 09, 2012
Re: Constraints
We can already kind of do what you're asking without a language 
feature. For instance, if you want to define that something is a 
type of range...

struct MyRange { ... }

static assert(isInputRange!MyRange); // won't compile unless 
MyRange is an input range

On Wednesday, 9 May 2012 at 15:04:51 UTC, İbrahim Gökhan 
YANIKLAR wrote:
> // implement foo's without constraints
> //------------------------------------------------------------
>
> void foo(Range)(Range r)
> 	if (isInputRange!Range && !isForwardRange!Range)
> { }
>
> void foo(Range)(Range r)
> 	if (isForwardRange!Range && !isBidirectionalRange!Range &&
> !isRandomAccessRange!Range)
> { }
>
> void foo(Range)(Range r)
> 	if (isBidirectionalRange!Range && !isRandomAccessRange!Range)
> { }
>
> void foo(Range)(Range r)
> 	if (isRandomAccessRange!Range)
> { }

And these could certainly use some library sugar. How about this:

template isJustInputRange(R) {
    enum bool isJustInputRange = isInputRange!R && 
!isForwardRange!R;
}

template isJustForwardRange(R) ...etc...
May 09, 2012
Re: Constraints
Allways we have some ways to do somethings.
The question is: which is better, easier and understandable.
I think my proposal is better.


> And these could certainly use some library sugar. How about 
> this:
>
> template isJustInputRange(R) {
>     enum bool isJustInputRange = isInputRange!R && 
> !isForwardRange!R;
> }

If we add for example isBufferedInputRange, we have to change 
isJustInputRange too. It's not a general solution.
May 09, 2012
Re: Constraints
what is the huge difference between D's current concepts - except that 
your idea allows to derive from concepts?

http://dlang.org/concepts.html
May 09, 2012
Re: Constraints
There is not a huge difference, but this idea can be extended.
After your reply, I have found this proposal for C++.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2081.pdf


On Wednesday, 9 May 2012 at 16:40:24 UTC, dennis luehring wrote:
> what is the huge difference between D's current concepts - 
> except that your idea allows to derive from concepts?
>
> http://dlang.org/concepts.html
May 09, 2012
Re: Constraints
We can not write a common interface for classes and structs. 
Concepts or constraints can provide that.
May 09, 2012
Re: Constraints
Am 09.05.2012 19:07, schrieb "İbrahim Gökhan YANIKLAR" 
<yanikibo@gmail.com>":
> We can not write a common interface for classes and structs.
> Concepts or constraints can provide that.

we can write a common interface for both - but not a contract checking one
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home