namespace Zinnia.Data.Type { using System; using System.Collections; using System.Collections.Generic; /// /// Represents a read-only collection of elements that can be accessed by index. Accessing it will not create any heap allocations. /// /// The type of the elements. public struct HeapAllocationFreeReadOnlyList : IReadOnlyList { /// /// Enumerates a . /// public struct Enumerator : IEnumerator { private readonly IList list; private readonly int start; private readonly int count; private int index; /// public T Current { get; private set; } /// object IEnumerator.Current { get { if (index == start || index == count + 1) { throw new InvalidOperationException(); } return Current; } } /// /// Creates a new that can enumerate the given . /// /// The list to enumerate. /// The index to start enumerating at. /// How many items to enumerate over. public Enumerator(IList list, int start, int count) { this.list = list ?? Array.Empty(); this.start = start; this.count = count; index = start; Current = default; } /// public void Dispose() { } /// public bool MoveNext() { if (index < count) { Current = list[index]; index++; return true; } index = count + 1; Current = default; return false; } /// public void Reset() { index = start; Current = default; } } private readonly IList list; private readonly int start; private readonly int count; /// public int Count => list?.Count ?? 0; /// public T this[int index] => (list ?? Array.Empty())[index]; /// /// Creates a new instance of . /// /// The list to enumerate. /// The index to start enumerating at. /// How many items to enumerate over. public HeapAllocationFreeReadOnlyList(IList list, int start, int count) { this.list = list; this.start = start; this.count = count; } /// /// Implicitly converts an instance of to a . /// /// The to convert. public static implicit operator HeapAllocationFreeReadOnlyList(List list) { return new HeapAllocationFreeReadOnlyList(list, 0, list?.Count ?? 0); } /// /// Implicitly converts an instance of to a . /// /// The to convert. public static implicit operator HeapAllocationFreeReadOnlyList(T[] array) { return new HeapAllocationFreeReadOnlyList(array, 0, array?.Length ?? 0); } /// /// Implicitly converts an instance of to a . /// /// The to convert. public static implicit operator HeapAllocationFreeReadOnlyList(ArraySegment arraySegment) { return new HeapAllocationFreeReadOnlyList(arraySegment.Array, arraySegment.Offset, arraySegment.Count); } /// /// Returns an enumerator that iterates through the elements. /// /// An enumerator to iterate through the elements. public Enumerator GetEnumerator() { return new Enumerator(list, start, count); } /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }