Table of Contents

Class LazyLinkedList<T>

Namespace
Hi.Common.Collections
Assembly
HiGeom.dll

A singly-growable linked list that can lazily materialize nodes from an IEnumerable<T> source.

Without a source it behaves like a regular append-only linked list. With a source, nodes are pulled on demand when Next is accessed on the tail, or when First is accessed on an empty list.
public class LazyLinkedList<T> : IEnumerable<T>, IEnumerable, IDisposable

Type Parameters

T
Inheritance
LazyLinkedList<T>
Implements
Inherited Members
Extension Methods

Examples

// Lazy: nodes materialize as you walk .Next
using var list = new LazyLinkedList<string>(File.ReadLines(path));
var node = list.First;          // materializes line 0
var next = node.Next;           // materializes line 1

// Manual: just like a regular linked list
var list2 = new LazyLinkedList<int>();
list2.AddLast(1);
list2.AddLast(2);

Constructors

LazyLinkedList()

Creates an empty list (no lazy source).

public LazyLinkedList()

LazyLinkedList(IEnumerable<T>)

Creates a list backed by a lazy source. Nodes are materialized on demand via Next or First.

public LazyLinkedList(IEnumerable<T> source)

Parameters

source IEnumerable<T>

Properties

Count

Number of nodes currently materialized in the list.

public int Count { get; }

Property Value

int

ExhaustedLast

Forces full materialization of the lazy source and returns the last node. Walks the source to completion (no-op if already exhausted), then returns Last. Use when callers need the definitive tail at this point in time (e.g. as a stable predecessor before AppendSource(IEnumerable<T>)).

public LazyLinkedListNode<T> ExhaustedLast { get; }

Property Value

LazyLinkedListNode<T>

First

Gets the first node, materializing from source if the list is empty.

public LazyLinkedListNode<T> First { get; }

Property Value

LazyLinkedListNode<T>

IsExhausted

Whether all items from the source have been materialized (or no source was provided).

public bool IsExhausted { get; }

Property Value

bool

Last

Gets the last materialized node in the list.

public LazyLinkedListNode<T> Last { get; }

Property Value

LazyLinkedListNode<T>

Methods

AddLast(T)

Appends a new node with the specified value to the end of the list.

public LazyLinkedListNode<T> AddLast(T value)

Parameters

value T

The value to add.

Returns

LazyLinkedListNode<T>

The newly created node.

AppendSource(IEnumerable<T>)

Appends a new lazy source after the current source. The existing source's remaining items (if any) are drained first, then the new source is yielded. Re-opens the list for further on-demand materialization, so calling Next on the prior tail materializes the next item and links Previous across the boundary.

public void AppendSource(IEnumerable<T> src)

Parameters

src IEnumerable<T>

The new source to append.

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose()

GetEnumerator()

Returns an enumerator that iterates through the collection.

public IEnumerator<T> GetEnumerator()

Returns

IEnumerator<T>

An enumerator that can be used to iterate through the collection.

PrependSource(IEnumerable<T>)

Prepends a new source ahead of the current source's remaining items. On the next on-demand materialization (triggered by Next on the present tail or First on an empty list), src is yielded first; once exhausted, the previous source's untouched tail resumes. The materialized prefix of the list — including the present tail — is unaffected, so this is the natural way to splice extra items in immediately after the current tail (for example, inlining an M98 subprogram's blocks after the host node so the rest of the pipeline picks them up via ordinary walkNode.Next traversal).

public void PrependSource(IEnumerable<T> src)

Parameters

src IEnumerable<T>

The source to insert ahead of the remaining items.

Remarks

Constraint: the caller must treat the present tail as the splice point. There is no way to prepend “after some interior node” — the prepended items are queued ahead of whatever the current source would have produced next. Use this when the splice point coincides with the tail at the moment of the call (which is how SoftNcRunner's pipeline drives node-by-node lazy materialization in lock-step with syntax/semantic processing).

ReplaceSource(IEnumerable<T>)

Replaces the current source's remaining items with src. Discards anything the old source had queued (it is disposed); the next on-demand materialization (triggered by Next on the present tail or First on an empty list) yields from src only. Already-materialized nodes — including the present tail — are unaffected, so this is the natural way to redirect future execution from the current tail onwards (for example, a GOTO that re-segments the file from the target N{seq} line: the GOTO host block stays materialized as the predecessor, and the post-target re-segmentation becomes the new source while the original between-here- and-EOF source is dropped).

public void ReplaceSource(IEnumerable<T> src)

Parameters

src IEnumerable<T>

The new source. Yielded from on the next materialization.

Remarks

Constraint: same as PrependSource(IEnumerable<T>) — the present tail is the splice point. Differs from PrependSource(IEnumerable<T>) in that the old source's untouched tail is NOT preserved after src runs out; ReplaceSource(IEnumerable<T>) drops it. Use PrependSource(IEnumerable<T>) for inline expansion (M98 / G65) where the caller's tail must resume after the inlined body; use ReplaceSource(IEnumerable<T>) for control-flow redirection (GOTO, M99 P{seq}) where the original tail is no longer reachable.