On Wed, 12 Jun 2013 22:54:19 -0400, deadalnix <[email protected]> wrote:

On Wednesday, 12 June 2013 at 19:00:28 UTC, Steven Schveighoffer wrote:
Yes, I could introduce it like this:

struct range(inout U) if(is(U == T))
{
   size_t length;
   U *ptr;
}

but it feels unnecessary. I also find the usage for this solution clumsy.


Why would you need to do it ? Why not simply do :

class Container(T) {
     struct range {
         size_t length;
         T* ptr;
     }
}

if, for instance, I want to accept a container and promise not to modify the elements, I would have:

void foo(const Container!int cont);

OK, so, in order to access a range of elements from the container, the container would have some kind of function, like:

range findAll(T elem);

How to mark up this function so it's callable on a const Container?

For C++, their solution (at least for C++03, I haven't checked how this works for C++11) is to simply define iterator and const_iterator separately, and then each function is duplicated, one that returns iterator and one that is const and returns const_iterator.

But I don't like that :) I want to use inout to avoid duplication. I *also* want to have a function like this:

void processRange(R)(R r) if(isInputRange!R)

And mark up processRange so *it* states that it won't modify the data. Then I can do:

processRange(cont.findAll(1));

on a mutable C named cont.

Basically, I'm spoiled by how well D slices work :)  I want the same power.

-Steve

Reply via email to