On 2010-01-29 11:54:41 -0500, "Steven Schveighoffer"
<[email protected]> said:
On Fri, 29 Jan 2010 11:33:17 -0500, Michel Fortin
<[email protected]> wrote:
On 2010-01-29 11:18:46 -0500, Andrei Alexandrescu
<[email protected]> said:
It should work for stream ranges if front() checks the "filled" flag
and eats the next line if false, and popFront clears the "filled" flag.
So now you want the front to fetch from stdin on the first call? It's
the same problem as 'byLine' eating the first line when you create it:
neither one or the other should affect the stream.
No, you're reaching here :) What Andrei is doing is acknowledging that
front has already performed the job of popFront. Because of the
nature of streams, you cannot get the data from the stream, and leave
it on the stream at the same time. It's just not feasible.
What the solution Andrei came up with does is to make stream ranges
behave as close as possible to forward ranges. That small
inconsistency will not hurt you because most of the time you are not
calling front for an element you don't intend to use. And even within
that paradigm, you are even less likely to use the stream in another
capacity.
"will not hurt because most of the time"... surely you meant "will not
hurt most of the time because". You're acknowledging it's an
inconsistency and that it'll hurt.
In other words, as the last usage of a range in an algorithm function, this:
r.front;
r.popFront();
is way more likely than:
r.popFront()
r.front;
Yeah, it's less likely to be a problem. But "less likely to be a
problem" does still does not make things reliable. Something reliable
works all the time, or it just doesn't work and tells you.
And I'd argue that it's very likely that an algorithm hits the problem,
check this:
skipEmptyLines(stdin.byLine);
string line = stdin.readln;
void skipEmptyLines(R)(R range) {
while (!range.empty && range.front == "")
range.popFront;
}
skipEmptyLine works right with ranges, but not with a stream. On the
last loop, it calls range.front, which removes a line from the stream,
and then say it's finished.
The truth is that this algorithm doesn't work with streams as it relies
on a buffer being available. But it still compiles, silently
introducing a bogus behaviour. If byLine defined only a 'take'
function, we wouldn't have this problem as skipEmptyLines wouldn't
compile, forcing you to use some kind of buffered stream or another
algorithm that works correctly with streams.
--
Michel Fortin
[email protected]
http://michelf.com/