Interfaces, traits, concepts, and my idea for a DIP

jmh530 via Digitalmars-d digitalmars-d at puremagic.com
Fri Jul 31 09:28:28 PDT 2015


On Friday, 31 July 2015 at 14:24:58 UTC, Atila Neves wrote:
>
> Notice however, that (again, in the PR), the "real" definition 
> happens only once, in the check function. Then the constraint 
> is always a trivial `enum MyConstraint = 
> is(typeof(myCheckFunction));`. It's just a matter of moving the 
> lambda away, giving it a name, and doing the weird 
> `if(!__ctfe)` hack.
>
> Atila

Looking at the PR also resolved my earlier question. Running the 
code as below (do not import std.range) will tell you exactly 
what isn't implemented from isInputRange (in this case, I 
commented out popFront). Very cool.

template satisfies(alias Constraint, R) {
     enum check = "check" ~ Constraint.stringof[2..$-3] ~ "!(R)";
     enum assert_ = "static assert("~ check ~ ");";
     mixin(assert_); //mixes in "static assert(checkInputRange!R)"
}

template isInputRange(R)
{
     enum bool isInputRange = is(typeof(checkInputRange!R));
}

bool checkInputRange(R)(inout int = 0)
{
     if (__ctfe)
     {
         R r = R.init;     // can define a range object
         if (r.empty) {}   // can test for empty
         r.popFront();     // can invoke popFront()
         auto h = r.front; // can get the front of the range
     }
     return true;
}

@satisfies!(isInputRange, Zeroes)
struct Zeroes {
     enum empty = false;
     //void popFront() {}
     @property int front() { return 0; }
}

void main()
{
	Zeroes Z;
}



More information about the Digitalmars-d mailing list