concept CInputRange(R)
{
        static assert (isDefinable!R);
        static assert (isRange!R);
        bool empty();
        void popFront();
        ElementType!R front();
}

concept CForwardRange(R) : CInputRange!R
{
        R save();
}

concept CBidirectionalRange(R) : CForwardRange!R
{
        void popBack();
        ElementType!R back();
}

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

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

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

struct InputRange : CInputRange;
// same as struct InputRange : CInputRange!InputRange

struct ForwardRange;
// Satisfies CForwardRange concept but don't apply it

interface IBidirectionalRange : CBidirectionalRange;
// Apply concept to the classes derived from IBidirectionalRange

class BidirectionalRange : IBidirectionalRange;
// Implement IBidirectionalRange and apply CBidirectionalRange

struct RandomAccessFinite : CRandomAccessRange;

struct RandomAccessInfinite : CRandomAccessRange;

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

void foo(Range : CInputRange)(Range r) { }
void foo(Range : CForwardRange)(Range r) { }
void foo(Range : CBidirectionalRange)(Range r) { }
void foo(Range : CRandomAccessRange)(Range r) { }

Reply via email to