Definition of "OutputRange" insuficient
monarch_dodra
monarchdodra at gmail.com
Tue Jul 17 08:36:44 PDT 2012
> 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 :/
More information about the Digitalmars-d
mailing list