OutputRange is designed for infinite output ranges, like output files and appender.

[snip]

Well, "designed" is open for interpretation.

Yes, all (most) "ranges defined as output" (files, streams, appenders) are infinite, and don't define empty (or define it as false).

But that does not mean that all ranges that fulfill "isOutputRange" are infinite. By leaving out the "empty" requirement from output range, we are forcing the infinity concept on anything that wishes to use the output facilities of a range.

On Tuesday, 17 July 2012 at 14:53:00 UTC, Andrei Alexandrescu wrote:
Actually if you look at put() it's designed to accept an input range with assignable elements, in which case it assigns to the front and moves forward. But I agree we could improve output ranges with a notion of "full". The paradox is, for an input range used for output, "full" is a synonym for "empty" :o).

Andrei

Well, the "underlying" container being full makes the range empty. I don't really see how we could have a notion of a "full range". But I'll admit the contrast if funny to observe :D

Regarding put, I noticed that actually. I was going to propose using it in "copy", as it could probably improve performance in the "generic case" (that, and it is _meant_ to be used that way). Right now, it defines a "genericImplementation" as:

--------
    static Range2 genericImpl(Range1 source, Range2 target)
    {
        for (; !source.empty; source.popFront())
        {
            put(target, source.front);
        }

        return target;
    }
--------
which should really just be
--------
    static Range2 genericImpl(Range1 source, Range2 target)
    {
        put(target, source);
        return target;
    }
--------
In the case of "fill" is that "put" will throw an exception if source does fit into target. There is no real way to know this before hand either, and it is not possible to just insert until full: That is the entire problem.

An easy fix at this point would be to just provide "hasEmpty", no? After all, we have "hasLength". That said, I feel this is more a bandage, and that outputRange really should define empty.

--------
On a same note, I just noticed that "forwardRange" does not have to adhere to the "outputRange" concept. This is in stark opposition to the classification in C++. Is this on purpose? I took it for granted that "forward" meant "output"+"input"+"save", but it is really just "input"+"save".

In theory, this means that the only "safe" way to write to a range would be to use "put".

There is a "hasAssignableElements" trait, but the requirements are odd: 1) It requires the range to be at least "forward", meaning an inputRange or an outputRange (!) will fail the "hasAssignableElements" test. 2) It only checks that "front" is assignable, so that does not guarantee you can assign to the indexes of a RandomAccess range :/

Reply via email to