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.

Reply via email to