I'd love to see this used more in Phobos. I don't know if there are any drawbacks, but this looks and works nicely:
import std.stdio : writeln; void main() { writeln(isInputRange!(N)); } class N { N test; bool empty() { return false; } @property void popFront() { } @property N front() { return test; } } template isInputRange(R) { enum bool isInputRange = __traits(compiles, { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }); } If you uncomment some of those methods in class N, then you get back false, which is what you want. Currently isInputRange is defined like so in Phobos: template isInputRange(R) { enum bool isInputRange = is(typeof( { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }())); } It's getting close to LISP! :) Andrej Mitrovic Wrote: > Yeah, that could work: > > template isInputRange(R) > { > enum bool isInputRange = __traits(compiles, > { > R r; // can define a range object > if (r.empty) {} // can test for empty > r.popFront; // can invoke next > auto h = r.front; // can get the front of the range > }); > } > > It does look nice. It would look even nicer if __traits gets renamed to meta. > > Stanislav Blinov Wrote: > > > What about __traits(compiles) ? >