ListSegment<T>
public struct ListSegment<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IReadOnlyCollection<T>
Delimits a section of a list.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DotNext.Collections.Generic
{
[StructLayout(LayoutKind.Auto)]
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public readonly struct ListSegment<[System.Runtime.CompilerServices.Nullable(2)] T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IReadOnlyCollection<T>
{
private readonly int startIndex;
private readonly IList<T> list;
bool ICollection<T>.IsReadOnly {
get {
return true;
}
}
public int Count { get; }
public T this[int index] {
get {
return list[ToAbsoluteIndex(index)];
}
set {
list[ToAbsoluteIndex(index)] = value;
}
}
public ListSegment(IList<T> list, Range range)
{
(int, int) offsetAndLength = range.GetOffsetAndLength(list.Count);
startIndex = offsetAndLength.Item1;
Count = offsetAndLength.Item2;
this.list = list;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int ToAbsoluteIndex(int index)
{
if (!Comparison.Between<int>(index, 0, Count, BoundType.LeftClosed))
throw new ArgumentOutOfRangeException("index");
return index + startIndex;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool ToRelativeIndex(ref int index)
{
index -= startIndex;
return Comparison.Between<int>(index, 0, Count, BoundType.LeftClosed);
}
public int IndexOf(T item)
{
int index = list.IndexOf(item);
if (!ToRelativeIndex(ref index))
return -1;
return index;
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
throw new NotSupportedException();
}
public bool Contains(T item)
{
return IndexOf(item) >= 0;
}
public void CopyTo(T[] array, int arrayIndex)
{
IList<T> list = this.list;
List<T> list2 = list as List<T>;
if (list2 == null) {
T[] array2 = list as T[];
if (array2 != null)
Array.Copy(array2, startIndex, array, arrayIndex, Count);
else {
for (int i = 0; i < Count; i++) {
array[i] = this.list[i + startIndex];
}
}
} else
list2.CopyTo(startIndex, array, arrayIndex, Count);
}
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
public IEnumerator<T> GetEnumerator()
{
IEnumerator<T> enumerator = list.GetEnumerator();
Sequence.Skip<T>(enumerator, startIndex);
return Sequence.Limit<T>(enumerator, Count, false);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}