I recently required a function to return an input range over some
base element type E. I was under the impression that this is
exactly what the interfaces in std.range.interface are for but
found that these are more restrictive than the checks from
std.range.primitives.
In particular, isInputRange(R) only requires R to implement
front, empty and popFront, while InputRange!E requires moveFront
and opApply in addition. To me this was unexpected and seems
inconsistent, but maybe there's a good reason for that.
Can someone explain whether (and why) this is intentional.