On Saturday, 23 February 2013 at 20:28:43 UTC, Steven
Schveighoffer wrote:
On Sat, 23 Feb 2013 10:34:18 -0500, deadalnix
<[email protected]> wrote:
On Saturday, 23 February 2013 at 15:16:15 UTC, Steven
Schveighoffer wrote:
This actually is impossible to do with inout, unless your
ranges are pointers or arrays (believe me, I tried with
dcollections). But that is not inout's fault, it's because
we have no way to specify tail-const arbitrary types.
I have read what come after, but clearly shouldn't have. This
is the interesting thing to discuss. Can you expand on that ?
Some code sample ?
OK, here is a simple abstract example (the implementation
details are not important, just the interface).
class Container(T)
{
...
struct range
{
...
@property inout(T) front() inout {...}
void popFront() {...}
bool empty() const { ...}
}
inout(range) opSlice() inout {...}
}
Nice, right? But it doesn't work, for one simple reason:
popFront.
const Container!int cont = new Container!int(...);
auto r = cont[];
foreach(const x; r)
{
writeln(x);
}
doesn't work! typeof(r) is const(Container!(int).range), and
since popFront is not const (and cannot be), you cannot iterate!
Obviously ! You need a mutable range of const elements, not a
const range.
What you need is a SEPARATE "const_range" type (this is similar
to C++). Then opSlice() const will return const_range.
In C++, const_iterator are iterator of const elements. They are
not const themselves.
And const range and range are not related, they are separate
types. So there is no way to have inout choose the right one!
They are indeed different types, but are exactly the same at the
end except mangling. That is the real problem that have to be
solved.