Constraints

Ibrahim Gokhan YANIKLAR yanikibo at gmail.com
Fri May 11 03:06:22 PDT 2012


On Friday, 11 May 2012 at 07:58:54 UTC, 
travert at phare.normalesup.org (Christophe Travert) wrote:
> "Ibrahim Gokhan YANIKLAR" , dans le message 
> (digitalmars.D:166850), a
>  écrit :
>
> I would even have:
>
> concept CInputRange(E)
> {
> 	alias E ElementType;
> 	static assert (isDefinable!typeof(this));
> 	static assert (isRange!typeof(this));
> 	@property bool empty();
> 	@property void popFront();
> 	@property ElementType front();
> }
>
> Concepts allows to state your intent when you create a type. It 
> self
> documents the code more nicely that a static assert. It would be
> much easier for newcomers to understand concepts. Finally, by 
> creating a
> hierarchy, concepts allows to determine which is the more 
> specialized
> template. Even if it is not a priority to add this to the 
> langage, I
> don't think it is just syntactic sugar.
>
>
> Several problems should be solved though:
>
> concept CInfiniteRange(E) : CInputRange(E)
> {
> // empty was declared to be a property, here it is an enum.
>       enum bool empty = false;
> // or:
>       final bool empty() { return false; }
> }
>
> struct SimpleCounter(E) : CInfiniteRange(E)
> {
> // front was declared as a property, here it is a member 
> variable
>     E front = 0;
>     void popFront() { ++front; }
> //or:
>     E front_ = 0;
>     @property E front() const { return front_; } // now front 
> is const
>     @property void popFront() { ++front_; }
> }
>
> It will not be obvious to define what is allowed and what is 
> not so that
> the flexibility of current template constraints is reached, 
> while
> keeping the definition natural.


Fixed:


concept CInputRange(R, E, T = E)
{
	static assert (isDefinable!R);
	static assert (isRange!R);
	@property bool empty();
	void popFront();
	@property E front();
	static assert (isImplicitlyConvertible!(E, T));
}

concept CForwardRange(R, E, T = E) : CInputRange!(R, E, T)
{
	@property R save();
}

concept CBidirectionalRange(R, E, T = E) : CForwardRange!(R, E, T)
{
	void popBack();
	@property E back();
}

concept CRandomAccessRange(R, E, T = E) : CBidirectionalRange!(R, 
E, T)
	if (!isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
	static assert(hasLength!R);
	static assert(!isNarrowString!R);
}

concept CRandomAccessRange(R, E, T = E) : CForwardRange!(R, E, T)
	if (isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
}


Using the first template parameter as typeof(this) is more 
effective.
The ElementType ( E ) can be deduced from the type ( or return 
type ) of front.
When we declare front as a property, it should match both 
property functions and enums.



More information about the Digitalmars-d mailing list