Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
195 lines (163 sloc) 5.11 KB
using System;
using System.Collections;
using System.Collections.Generic;
namespace CookComputing.Collections
{
public struct SubArray<T> : IList<T>
{
readonly T[] _array;
readonly int _offset;
readonly int _count;
public SubArray(T[] array)
{
if (array == null) throw new ArgumentNullException("array");
_array = array;
_offset = 0;
_count = array.Length;
}
public SubArray(T[] array, int offset, int count)
{
if (array == null) throw new ArgumentNullException("array");
_array = array;
_offset = offset;
_count = count;
CheckArgs(array, offset, count);
}
public SubArray(SubArray<T> subArray)
{
if (subArray == null) throw new ArgumentNullException("subArray");
_array = subArray.Array;
_offset = subArray.Offset;
_count = subArray.Count;
}
public SubArray(SubArray<T> subArray, int subArrayOffset, int count)
{
if (subArray == null) throw new ArgumentNullException("subArray");
_array = subArray.Array;
_offset = subArray.Offset + subArrayOffset;
_count = count;
CheckArgs(subArray, subArrayOffset, count);
}
public T[] Array { get { return _array; } }
public int Offset { get { return _offset; } }
public int Count { get { return _count; } }
public int IndexOf(T item)
{
Comparer<T> comparer = Comparer<T>.Default;
for (int i = 0; i < Count; i++)
{
if (comparer.Compare(item, Array[Offset + i]) == 0)
return i;
}
return -1;
}
public T this[int index]
{
get
{
if (index < 0 || index >= Count)
throw new IndexOutOfRangeException(MSG_INDEXBOUNDS);
return Array[Offset + index];
}
set
{
throw new NotSupportedException(MSG_FIXEDSIZE);
}
}
public void Clear()
{
for (int i = 0; i < Count; i++)
Array[Offset + i] = default(T);
}
public bool Contains(T item)
{
return IndexOf(item) >= 0;
}
public void CopyTo(T[] array, int arrayIndex)
{
for (int i = 0; i < Count; i++)
{
array[arrayIndex + i] = Array[Offset + i];
}
}
public bool IsReadOnly
{
get { return Array.IsReadOnly; }
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < Count; i++)
yield return Array[Offset + i];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Insert(int index, T i)
{
throw new NotSupportedException(MSG_FIXEDSIZE);
}
public void RemoveAt(int index)
{
throw new NotSupportedException(MSG_FIXEDSIZE);
}
public void Add(T item)
{
throw new NotSupportedException(MSG_FIXEDSIZE);
}
public bool Remove(T item)
{
throw new NotSupportedException(MSG_FIXEDSIZE);
}
public override int GetHashCode()
{
return Array.GetHashCode() ^ Offset ^ Count;
}
public override bool Equals(object obj)
{
return obj is SubArray<T> && this.Equals((SubArray<T>)obj);
}
public bool Equals(SubArray<T> subArray)
{
return subArray.Array == Array && subArray.Offset == Offset
&& subArray.Count == Count;
}
public static bool operator ==(SubArray<T> a, SubArray<T> b)
{
return a.Equals(b);
}
public static bool operator !=(SubArray<T> a, SubArray<T> b)
{
return !(a == b);
}
private void CheckArgs(IList<T> parent, int offset, int length)
{
if (offset < 0 || offset >= parent.Count)
throw new ArgumentOutOfRangeException("offset");
if (length < 0 || length > (parent.Count - offset))
throw new ArgumentOutOfRangeException("count");
}
const string MSG_FIXEDSIZE = "Collection was of a fixed size.";
const string MSG_INDEXBOUNDS = "Index was outside the bounds of the array";
}
public static class SubArrayExtensions
{
static public SubArray<T> SubArray<T>(this T[] array)
{
return new SubArray<T>(array);
}
static public SubArray<T> SubArray<T>(this T[] array, int offset, int count)
{
return new SubArray<T>(array, offset, count);
}
static public SubArray<T> SubArray<T>(this SubArray<T> subArray)
{
return new SubArray<T>(subArray);
}
static public SubArray<T> SubArray<T>(this SubArray<T> subArray, int offset,
int count)
{
return new SubArray<T>(subArray, offset, count);
}
}
}