Class ReplayableSequence<T>
- Namespace
- PatternKit.Behavioral.Iterator
- Assembly
- PatternKit.Core.dll
A replayable, forkable, lookahead-capable sequence abstraction that augments IEnumerable<T> when you need multi-pass / speculative traversal without re-enumerating or re-materializing the original source.
public sealed class ReplayableSequence<T>
Type Parameters
TElement type.
- Inheritance
-
ReplayableSequence<T>
- Inherited Members
Remarks
Why? Standard IEnumerable<T> is single forward pass per enumerator. To implement lookahead, backtracking, or parallel cursors you typically buffer, or you fully materialize into an array/list and index it. ReplayableSequence<T> sits in between: it buffers on demand as cursors ask for items. Every element is pulled from the underlying source at most once, appended to an internal buffer, then served from that buffer to any number of forks / cursors.
Core ideas:
- Cursor: lightweight value struct holding an index into a shared buffer.
- On-demand buffering: elements materialize only when first requested (via
TryNext,PeekorLookahead). - Fork: create an independent cursor snapshot at the current position.
- Lookahead: inspect future elements without advancing (parser / tokenizer friendly).
- LINQ interop: any cursor can be projected to an IEnumerable<T> without changing its own position.
Thread-safety: Concurrent readers (cursors / enumeration) are supported; the first-touch buffering operation is synchronized so elements are pulled from the underlying enumerator at most once. Writes only occur during initial enumeration into the internal buffer; after exhaustion the buffer is immutable.
Methods
AsAsyncEnumerable(CancellationToken)
Exposes the sequence as an IAsyncEnumerable<T> (synchronous push under the hood).
public IAsyncEnumerable<T> AsAsyncEnumerable(CancellationToken ct = default)
Parameters
Returns
AsEnumerable()
Enumerates the entire (shared) sequence as an IEnumerable<T>.
public IEnumerable<T> AsEnumerable()
Returns
- IEnumerable<T>
Remarks
Each enumeration uses a new starting cursor. Already buffered elements are reused; remaining ones stream in.
From(IEnumerable<T>)
Create a replayable wrapper over source.
public static ReplayableSequence<T> From(IEnumerable<T> source)
Parameters
sourceIEnumerable<T>
Returns
GetCursor()
Obtain a fresh cursor at the start (position 0).
public ReplayableSequence<T>.Cursor GetCursor()