One direction that _could_ be helpful, perhaps, is to extend
the concept
of range to include, let's tentatively call it, a ChunkedRange.
Basically a ChunkedRange implements the usual InputRange
operations
(empty, front, popfront) but adds the following new primitives:
- bool hasAtLeast(R)(R range, int n) - true if underlying range
has at
least n elements left;
I think it would be better to have a function that would return
the number of elements left.
- E[] frontN(R)(R range, int n) - returns a slice containing
the front n
elements from the range: this will buffer the next n elements
from the
range if they aren't already; repeated calls will just return
the
buffer;
- void popN(R)(R range, int n) - discards the first n elements
from the
buffer, thus causing the next call to frontN() to fetch more
data if
necessary.
I like the idea of frontN and popN. But is there any reason why
a type that defines those (let's call it a stream) should also
be a range? I would prefer to have a type that just defines those
two functions, a function that returns the number of available
elements and a functions that tells whether we are at the end of
stream. If you need a range of elements with a blocking popFront,
it's easy to build one on top of it. You can write a functions
that takes any stream and returns a range of element. I think
that's better than having to write front, popFront, and empty
for every stream.