In wake of a few discussion I've witnessed, I'm thinking of a last change for ranges. (In fact there's one more, but that's minor.)

The problem is that input ranges and forward ranges have the same syntactic interface, but different semantic interfaces. Consider the problem of finding the first two identical adjacent items in a range:

R adjacentFind(R)(R r)
{
    if (r,empty) return r;
    R last = r;
    r.popFront;
    for (; !r.empty && last.front != r.front; last.popFront, r.popFront)
    {
    }
    return r;
}

This will work properly on lists and vectors, but horrendously on files and sockets. This is because input ranges can't be saved for later use: incrementing r also increments popFront and essentially forces both to look at the same current value.

I'm thinking a better design is to require any range that's forward or better to define a function save(). Ranges that don't implement it are input ranges; those that do, will guarantee a brand new range is returned from save(). So then adjacentFind would look like this:

R adjacentFind(R)(R r)
{
    if (r,empty) return r;
    R last = r.save;
    r.popFront;
    for (; !r.empty && last.front != r.front; last.popFront, r.popFront)
    {
    }
    return r;
}

Obviously, when you pass a range that doesn't support save, adjacentFind will not compile, which is what we want.

Andrei

P.S. There is a way to implement adjacentFind for forward ranges by saving data instead of ranges. I've used a limited version above for illustration purposes.

Reply via email to