Definition of "OutputRange" insuficient
monarch_dodra
monarchdodra at gmail.com
Tue Jul 17 03:44:35 PDT 2012
I was trying to fix a few bugs in algorithm, as well as be more
correct in template type specifiers, and I have to say: There is
a serious restraint in the definition of an outputRange.
The current definition of "isOutputRange" is simply that "an
output range is defined functionally as a range that supports the
operation put".
The problem with this is this definition is not very useful (at
all). Not just because it lacks front/popFront (this is actually
OK). It is because it lacks an "empty". This makes it virtually
un-useable unless you are blind writing to an infinite output
range.
The proof that it is useless is that NOT A SINGLE ALGORITHM is
compatible with output ranges. All algorithms that really only
require an "output" systematically actually require
"isForwardRange", or, worse yet "isInputRange" (!). This is only
because they all make use of range.empty.
Here is an example of me trying to write "fill" respecting output
range restrictions.
----
void fill(Range1, Range2)(Range1 range, Range2 filler)
if (isOutputRange!(Range1, ElementType!Range2) &&
isForwardRange!Range2)
{
enforce(!filler.empty);
auto t = filler.save;
while (!range.empty) //Crud...
{
if (t.empty) t = filler.save;
put(range, t.front);
t.popFront();
}
}
----
Almost... but no cookie.
If the argument against this is "but the output range "can't know
if it empty"/"may never be empty", then is why we have an
"isInfinite" definition... isn't it?
On the same note, why is the definitions of "inputRange" so
divergent from outputRange. Shouldn't inputRange's definition
mirror output's and be "supports get" (and "is empty")?
Shouldn't a correct "front/popFront" _only_ be required once we
reach "forwardRange" and it's ability to save?
Here is an example of an implementation of fill, that only
requires the filler to be an input range, if it has infinity.
----
void fill(Range1, Range2)(Range1 range, Range2 filler)
if (isOutputRange!(Range1, ElementType!Range2) &&
isInputRange!Range2
&& isInfinite!Range2)
{
while( !range.empty )
{
put(range, get(filler));
}
}
----
The current definition makes anything like near impossible.
More information about the Digitalmars-d
mailing list