11/4/2012 7:16 PM, Andrei Alexandrescu пишет:
On 11/4/12 9:36 AM, deadalnix wrote:
Let's put back relevant elements of the solution I propose :
1/ range preserve .front by default .
2/ Ranges that would get performance boost from invalidating .front can
propose a property (we called it .fast in the thread) that return a new
range that invalidate .front .
IMHO this property is deducible from the others:
fast!R == isInputRange!R && !isForwardRange!R &&
hasMutableIndirections!(ElementType!R)
Or rather onePass!R == ...
but I seriously doubt that ability to save iteration state and the fact
of reusing single slot/memory chunk for .front are always correlated.
I think it would be vastly better to avoid defining a new property of
ranges (that subsequently would need to be cross-checked by many
algorithms). Then we have additional scalability issues because all
derived ranges would need to propagate .fast etc. Then we need to cater
for odd cases such as random-access ranges being .fast.
Neither .fast nor separate transient flag strike me as good solutions as
placing a lot of burden on the range implementer (and introducing yet
another convention).
The simpler way would be to simply state that input ranges can't
guarantee the persistence of .front after calling .popFront. This is
quite expected for input ranges, and no different for any object that
gives a char[]-based API; subsequently changing the object may change
the contents of the char[] returned.
The algorithms that need to worry about .front's transience are only the
ones that work with input ranges (as opposed to forward ranges or
stronger).
The fact that algorithm doesn't save iteration state != it counts on
transient .front.
A simple example of std.array.array will do - it iterates range once and
pumps elements into appender/builder "sink". So it doesn't require
forward range but just that elements are not _aliased_ under the hood.
Another example is dirEntries - it returns entries with immutable
strings, but it can't save iteration state. It does work with array
because of no aliasing of .front values.
This approach puts the burden in the right place - on the
implementers of specific algorithms supporting one-pass streaming.
Aside from mixing separate concepts into one* I like the approach.
*InputRange vs ForwardRange has nothing to do with mutable indirections
of .front.
--
Dmitry Olshansky