I don't think this is a good idea. Say you have a class with
range methods and add opApply later. Only the opApply delegate
receives a type other than size_t for the first argument. Now the
foreach line infers a differnt type for i and code in the outside
world will break.
More importantly, this gets in the way of behaviour which may be
desirable later, foreach being able to unpack tuples from ranges.
I would like if it was possible to return Tuple!(A, B) from
front() and write foreach(a, b; range) to interate through those
thing, unpacking the values with an alias, so this...
foreach(a, b; range) {
}
... could rewrite to roughly this. (There may be a better way.)
foreach(_someInternalName; range) {
alias a = _someInternalName[0];
alias b = _someInternalName[1];
}
Then to get a counter with a range, we could follow Python's
example and use an enumerate function, which would take an
existing range and wrap it with a counter, so T maps to
Tuple!(size_t, T).
foreach(index, value; enumerate(range)) {
}
Which is rewritten to roughly this.
foreach(_bla; enumerate(range)) {
alias index = _bla[0];
alias value = _bla[1];
}
If we follow Python's example again, we could also support this
nested unpacking.
// Now written with UFCS instead.
foreach(index, (index_again, value); range.enumerate.enumerate) {
}
Which can rewrite to roughly this.
foreach(_bla; range.enumerate.enumerate) {
alias index = _bla[0];
alias index_again = _bla[1][0];
alias value = _bla[1][1];
}
I got off on kind of a tangent there, but there you go.