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();
}
}
}