Inspired by https://github.com/dlang/phobos/pull/5153, a great range type would be one that offers fixed lookaround. It works like any other range but has supplemental functions for lookahead and lookback.
r.lookahead!(a, b) yields a range looking up to a elements ahead and up to b elements back. These are accessible through two new APIs, e.g. ahead(k) and behind(k).
If r is a random-access range, the resulting range does NOT copy any elements and simply provides APIs on top of the random access primitives.
If r is weaker than random-access, it embeds a fixed-size buffer and moves through it with minimal effort.
Comment #1 by greeenify — 2017-03-02T01:39:50Z
A couple of questions to clarify:
1) popFront/popBack will move the fixed-size buffer, right?
For example:
10.iota.ahead(3).drop(2).writeln; // [2, 3, 4]
2)
> it embeds a fixed-size buffer and moves through it with minimal effort.
It's assumed are only shallow which can change?
auto arr = 10.iota.ahead(3);
auto a = arr[1..$]; // [1, 2]
arr.popFront;
auto b = arr[1..$]; // [2, 3]
With "minimal effort" a would be [2, 3] as well.
3) Should there be ahead!3 to allow using a static array as buffer in order to avoid allocation?
4) Should there be support for providing your custom allocator for the runtime flag to allow GC-free behavior?
Comment #2 by andrei — 2017-03-02T01:54:13Z
(In reply to greenify from comment #1)
> A couple of questions to clarify:
>
> 1) popFront/popBack will move the fixed-size buffer, right?
> For example:
>
> 10.iota.ahead(3).drop(2).writeln; // [2, 3, 4]
ahead(k) returns the kth element ahead of front, not a range.
> 2)
> > it embeds a fixed-size buffer and moves through it with minimal effort.
>
> It's assumed are only shallow which can change?
Affirmative.
Comment #3 by robert.schadek — 2024-12-01T16:29:55Z