Loose isForwardRange to something like:
isInputRange!R && is(Unqual!(ReturnType!((R r) => r.save)) == Unqual!R)
I'm writing functions that takes a range and produce another range, with the guarantee that the origin range is not changed. So I need save() to produce a non-const range from a const one, which does not meet the current isForwardRange criteria.
Comment #1 by simen.kjaras — 2018-03-08T09:34:04Z
I assume you meant isInputRange!(Unqual!R) in the first half there.
Now, the problem with this idea is that const(R) generally is not a forward range, or even an input range, and loosening the constraints really doesn't make it one.
For a quick example, consider const(int[]) arr. Can I call arr.popFront() to iterate over it? No, that would need to modify the range, and the range is const, so I can't. If isForwardRange!(const(int[])) returned true, that would give the impression that I could indeed change the range, and would wreak havoc with the whole idea of ranges.
Generally, I would simply suggest using isForwardRange!(Unqual!R), but it seems that's not enough in your case - you want something like this:
enum bool isConstForwardRange(R) = isForwardRange!(Unqual!R) && isForwardRange!(ReturnType!((R r) => r.save));
That's probably too niche to put in Phobos, but it should at least solve your problem here and how.