// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. // Copied from https://github.com/dotnet/corefx/blob/f17f1e847aeab830de77f8a46656339d7b0f1b43/src/System.Linq/src/System/Linq/SingleLinkedNode.cs using System.Collections.Generic; using System.Diagnostics; namespace System.Linq { /// /// An immutable node in a singly-linked list of items. /// /// The type of the node's item. internal sealed class SingleLinkedNode { /// /// Constructs a tail node. /// /// The item to place in the tail node. public SingleLinkedNode(TSource item) { Item = item; } /// /// Constructs a node linked to the specified node. /// /// The linked node. /// The item to place in this node. private SingleLinkedNode(SingleLinkedNode linked, TSource item) { Debug.Assert(linked != null); Linked = linked; Item = item; } /// /// The item held by this node. /// public TSource Item { get; } /// /// The next node in the singly-linked list. /// public SingleLinkedNode Linked { get; } /// /// Creates a new node that holds the specified item and is linked to this node. /// /// The item to place in the new node. public SingleLinkedNode Add(TSource item) => new SingleLinkedNode(this, item); /// /// Gets the number of items in this and subsequent nodes by walking the linked list. /// public int GetCount() { var count = 0; for (var node = this; node != null; node = node.Linked) { count++; } return count; } /// /// Gets an that enumerates the items of this node's singly-linked list in reverse. /// /// The number of items in this node. public IEnumerator GetEnumerator(int count) { return ((IEnumerable)ToArray(count)).GetEnumerator(); } /// /// Gets the node at a logical index by walking the linked list. /// /// The logical index. /// /// The caller should make sure is less than this node's count. /// public SingleLinkedNode GetNode(int index) { Debug.Assert(index >= 0 && index < GetCount()); var node = this; for (; index > 0; index--) { node = node.Linked; } Debug.Assert(node != null); return node; } /// /// Returns an that contains the items of this node's singly-linked list in reverse. /// /// The number of items in this node. private TSource[] ToArray(int count) { Debug.Assert(count == GetCount()); var array = new TSource[count]; var index = count; for (var node = this; node != null; node = node.Linked) { --index; array[index] = node.Item; } Debug.Assert(index == 0); return array; } } }