On Friday, 11 May 2012 at 07:58:54 UTC, [email protected] (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.

Reply via email to