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

Reply via email to