Created
March 30, 2010 21:46
-
-
Save Nayruden/349633 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Collections; | |
public class Slice<T> : IList<T> | |
{ | |
private IList<T> backing_array; | |
private readonly int start; | |
private readonly int _count; | |
void checkArgs(IList<T> backing_array, int start, int end) | |
{ | |
if (start < 0 || start >= backing_array.Count || end <= 0 || end > backing_array.Count) | |
throw new IndexOutOfRangeException(); | |
if (end <= start) | |
throw new ArgumentOutOfRangeException("end", end, "Ending index must be greater than starting index"); | |
} | |
public Slice(IList<T> backing_array, int start, int end) | |
{ | |
checkArgs(backing_array, start, end); | |
this.backing_array = backing_array; | |
this.start = start; | |
this._count = end - start; | |
} | |
public Slice(Slice<T> slice, int start, int end) | |
{ | |
checkArgs(slice, start, end); | |
this.backing_array = slice.backing_array; | |
this.start = slice.start + start; | |
this._count = end - start; | |
} | |
public Slice<T> this[int start, int end] | |
{ | |
get { return new Slice<T>(this, start, end); } | |
} | |
public T this[int index] | |
{ | |
get | |
{ | |
if (index >= 0 && index < Count) | |
return backing_array[index + start]; | |
throw new IndexOutOfRangeException(); | |
} | |
set | |
{ | |
if (index >= 0 && index < Count) | |
backing_array[index + start] = value; | |
throw new IndexOutOfRangeException(); | |
} | |
} | |
public int IndexOf(T item) | |
{ | |
for (int i = 0; i < Count; i++) | |
if (EqualityComparer<T>.Default.Equals(item, this[i])) | |
return i; | |
return -1; | |
} | |
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] = this[i]; | |
} | |
public int Count | |
{ | |
get { return _count; } | |
} | |
public IEnumerator<T> GetEnumerator() | |
{ | |
for (int i = 0; i < Count; i++) | |
yield return backing_array[i + start]; | |
} | |
#region Explicit/Hidden Implementations | |
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(); | |
} | |
bool ICollection<T>.IsReadOnly | |
{ | |
get { return true; } | |
} | |
bool ICollection<T>.Remove(T item) | |
{ | |
throw new NotSupportedException(); | |
} | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return GetEnumerator(); | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using NUnit.Framework; | |
using System.Collections; | |
using System.Linq; | |
[TestFixture] | |
class SliceTest | |
{ | |
[Test] | |
public void BasicSlice() | |
{ | |
int[] range = { 1, 2, 3, 4, 5 }; | |
var slice = new Slice<int>(range, 0, range.Length); | |
Assert.AreEqual(range.Length, slice.Count); | |
Assert.AreEqual(range, slice); | |
// Test indexer | |
Assert.AreEqual(range[0], slice[0]); | |
Assert.AreEqual(range[1], slice[1]); | |
Assert.AreEqual(range[2], slice[2]); | |
Assert.AreEqual(range[3], slice[3]); | |
Assert.AreEqual(range[4], slice[4]); | |
// Test enumeration | |
int num = 1; | |
foreach (var i in slice) | |
Assert.AreEqual(i, num++); | |
// Test index of | |
Assert.AreEqual(slice.IndexOf(1), 0); | |
Assert.AreEqual(slice.IndexOf(4), 3); | |
Assert.AreEqual(slice.IndexOf(5), 4); | |
Assert.AreEqual(slice.IndexOf(0), -1); | |
// Test contains | |
Assert.True(slice.Contains(1)); | |
Assert.True(slice.Contains(2)); | |
Assert.True(slice.Contains(5)); | |
Assert.False(slice.Contains(0)); | |
slice = slice[1, slice.Count]; | |
Assert.AreEqual(range.Length - 1, slice.Count); | |
Assert.AreEqual(range.Skip(1), slice); | |
slice = slice[0, slice.Count - 1]; | |
Assert.AreEqual(range.Length - 2, slice.Count); | |
Assert.AreEqual(range.Skip(1).Take(3), slice); | |
// Test copy to | |
int[] copy = new int[5]; | |
new Slice<int>(range, 1, range.Length - 1).CopyTo(copy, 2); | |
Assert.AreEqual(range.Skip(1).Take(3), copy.Skip(2)); | |
} | |
[Test] | |
public void Asserts() | |
{ | |
int[] range = { 1, 2, 3, 4, 5 }; | |
int i; | |
var slice = new Slice<int>(range, 0, range.Length); | |
Assert.Throws(typeof(IndexOutOfRangeException), () => slice[-1] = 1); | |
Assert.Throws(typeof(IndexOutOfRangeException), () => slice[5] = 1); | |
Assert.Throws(typeof(IndexOutOfRangeException), () => i = slice[-1]); | |
Assert.Throws(typeof(IndexOutOfRangeException), () => i = slice[5]); | |
Assert.Throws(typeof(IndexOutOfRangeException), () => slice = slice[-1, 1]); | |
Assert.Throws(typeof(IndexOutOfRangeException), () => slice = slice[slice.Count, slice.Count]); | |
Assert.Throws(typeof(IndexOutOfRangeException), () => slice = slice[0, 0]); | |
Assert.Throws(typeof(IndexOutOfRangeException), () => slice = slice[0, slice.Count + 1]); | |
Assert.Throws(typeof(ArgumentOutOfRangeException), () => slice = slice[2, 2]); | |
slice = slice[1, slice.Count - 1]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment