If you use opDispatch to implement range primitives, isInputRange passes yet it cannot be used in foreach loops:
---
import std.range;
struct R {
auto vals = iota(0, 5);
auto opDispatch(string s)() { return mixin("vals."~s); }
// uncomment to pass:
//auto front() { return vals.front; }
//auto popFront() { return vals.popFront; }
//auto empty() { return vals.empty; }
}
// R is an input range, but cannot be used in foreach:
static assert(isInputRange!R); // pass
static assert(__traits(compiles, { foreach(v ; R()) { } })); // fail
---
We either need to allow foreach via opDispatched range primitives or have is*Range return false in this case.
Personally, I would like to see foreach work in this case, though there may be concerns over 'accidental' range implementation:
http://forum.dlang.org/thread/[email protected]
Comment #1 by robert.schadek — 2024-12-07T13:35:54Z