324 lines
8.2 KiB
C#
324 lines
8.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
|
|
namespace System.util.collections
|
|
{
|
|
public abstract class k_Iterator : IComparable, ICloneable
|
|
{
|
|
public static k_Iterator operator ++(k_Iterator ak_Iter)
|
|
{
|
|
return ak_Iter + 1;
|
|
}
|
|
|
|
public static k_Iterator operator --(k_Iterator ak_Iter)
|
|
{
|
|
return ak_Iter - 1;
|
|
}
|
|
|
|
public static k_Iterator operator +(k_Iterator ak_Iter, int ai_Distance)
|
|
{
|
|
k_Iterator lk_Clone = ak_Iter.Clone();
|
|
lk_Clone.Move(ai_Distance);
|
|
return lk_Clone;
|
|
}
|
|
|
|
public static k_Iterator operator -(k_Iterator ak_Iter, int ai_Distance)
|
|
{
|
|
k_Iterator lk_Clone = ak_Iter.Clone();
|
|
lk_Clone.Move(-ai_Distance);
|
|
return lk_Clone;
|
|
}
|
|
|
|
public static int operator -(k_Iterator ak_Left, k_Iterator ak_Right)
|
|
{
|
|
return ak_Left.Distance(ak_Right);
|
|
}
|
|
|
|
public static bool operator ==(k_Iterator ak_Left, k_Iterator ak_Right)
|
|
{
|
|
return object.Equals(ak_Left, ak_Right);
|
|
}
|
|
|
|
public static bool operator !=(k_Iterator ak_Left, k_Iterator ak_Right)
|
|
{
|
|
return !object.Equals(ak_Left, ak_Right);
|
|
}
|
|
|
|
public override bool Equals(object ak_Obj)
|
|
{
|
|
return base.Equals(ak_Obj); // implemented to avoid warning
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return base.GetHashCode(); // implemented to avoid warning
|
|
}
|
|
|
|
public int CompareTo(object ak_Obj)
|
|
{
|
|
k_Iterator lk_Iter = ak_Obj as k_Iterator;
|
|
if (lk_Iter == null || !object.ReferenceEquals(lk_Iter.Collection, this.Collection))
|
|
throw new ArgumentException("Cannot compare iterators of different origin.");
|
|
|
|
return Distance(lk_Iter);
|
|
}
|
|
|
|
object ICloneable.Clone()
|
|
{
|
|
return this.Clone();
|
|
}
|
|
|
|
public void Next()
|
|
{
|
|
Move(1);
|
|
}
|
|
|
|
public void Prev()
|
|
{
|
|
Move(-1);
|
|
}
|
|
|
|
public abstract object Current { get; set; }
|
|
public abstract object Collection { get; }
|
|
public abstract k_Iterator Clone();
|
|
|
|
public abstract void Move(int ai_Count);
|
|
public abstract int Distance(k_Iterator ak_Iter);
|
|
}
|
|
|
|
public class k_IteratorEnumerator : IEnumerator
|
|
{
|
|
protected k_Iterator mk_Current;
|
|
protected k_Iterator mk_Begin, mk_End;
|
|
protected bool mb_Fresh;
|
|
|
|
public k_IteratorEnumerator(k_Iterator ak_Begin, k_Iterator ak_End)
|
|
{
|
|
mk_Begin = ak_Begin;
|
|
mk_End = ak_End;
|
|
mb_Fresh = true;
|
|
}
|
|
|
|
#region IEnumerator Members
|
|
|
|
public bool MoveNext()
|
|
{
|
|
if (mb_Fresh)
|
|
{
|
|
mk_Current = mk_Begin.Clone();
|
|
mb_Fresh = false;
|
|
}
|
|
else if (mk_Current != mk_End)
|
|
mk_Current.Next();
|
|
|
|
return (mk_Current != mk_End);
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
mb_Fresh = true;
|
|
mk_Current = null;
|
|
}
|
|
|
|
public object Current
|
|
{
|
|
get
|
|
{
|
|
if (mb_Fresh || mk_Current == mk_End)
|
|
throw new InvalidOperationException("The enumerator is positioned before the first element of the collection or after the last element.");
|
|
return mk_Current.Current;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public class k_IteratorDictEnumerator : k_IteratorEnumerator, IDictionaryEnumerator
|
|
{
|
|
public k_IteratorDictEnumerator(k_Iterator ak_Begin, k_Iterator ak_End)
|
|
: base(ak_Begin, ak_End)
|
|
{
|
|
}
|
|
|
|
#region IDictionaryEnumerator Members
|
|
|
|
public object Key
|
|
{
|
|
get { return this.Entry.Key; }
|
|
}
|
|
|
|
public object Value
|
|
{
|
|
get { return this.Entry.Value; }
|
|
}
|
|
|
|
public DictionaryEntry Entry
|
|
{
|
|
get { return (DictionaryEntry)this.Current; }
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public class k_IListIterator : k_Iterator
|
|
{
|
|
private readonly IList mk_List;
|
|
private int mi_Index;
|
|
|
|
public static k_IListIterator CreateBegin(IList ak_List)
|
|
{
|
|
return new k_PinnedIListIterator(ak_List, 0);
|
|
}
|
|
|
|
public static k_IListIterator CreateEnd(IList ak_List)
|
|
{
|
|
return new k_PinnedIListIterator(ak_List, ak_List.Count);
|
|
}
|
|
|
|
public k_IListIterator(IList ak_List, int ai_Index)
|
|
{
|
|
mk_List = ak_List;
|
|
mi_Index = ai_Index;
|
|
}
|
|
|
|
public override void Move(int ai_Count)
|
|
{
|
|
int li_Index = mi_Index + ai_Count;
|
|
|
|
if (li_Index < 0)
|
|
throw new InvalidOperationException("Tried to move before first element.");
|
|
else if (li_Index > mk_List.Count)
|
|
throw new InvalidOperationException("Tried to moved beyond end element.");
|
|
|
|
mi_Index = li_Index;
|
|
}
|
|
|
|
public override int Distance(k_Iterator ak_Iter)
|
|
{
|
|
return mi_Index - ((k_IListIterator)ak_Iter).mi_Index;
|
|
}
|
|
|
|
public override object Collection
|
|
{
|
|
get { return mk_List; }
|
|
}
|
|
|
|
public override object Current
|
|
{
|
|
get
|
|
{
|
|
if (mi_Index < 0 || mi_Index >= mk_List.Count)
|
|
throw new k_InvalidPositionException();
|
|
return mk_List[mi_Index];
|
|
}
|
|
set
|
|
{
|
|
if (mi_Index < 0 || mi_Index >= mk_List.Count)
|
|
throw new k_InvalidPositionException();
|
|
mk_List[mi_Index] = value;
|
|
}
|
|
}
|
|
|
|
public override bool Equals(object ak_Obj)
|
|
{
|
|
k_IListIterator lk_Iter = ak_Obj as k_IListIterator;
|
|
if (lk_Iter == null)
|
|
return false;
|
|
return (mi_Index == lk_Iter.mi_Index) && object.ReferenceEquals(this.Collection, lk_Iter.Collection);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return mk_List.GetHashCode() ^ mi_Index;
|
|
}
|
|
|
|
public override k_Iterator Clone()
|
|
{
|
|
return new k_IListIterator(mk_List, mi_Index);
|
|
}
|
|
|
|
internal int Index
|
|
{
|
|
get { return mi_Index; }
|
|
}
|
|
}
|
|
|
|
internal class k_PinnedIListIterator : k_IListIterator
|
|
{
|
|
public k_PinnedIListIterator(IList ak_List, int ai_Index)
|
|
: base(ak_List, ai_Index)
|
|
{
|
|
}
|
|
|
|
public override void Move(int ai_Count)
|
|
{
|
|
throw new k_IteratorPinnedException();
|
|
}
|
|
}
|
|
|
|
public class k_CollectionOnIterators : ICollection
|
|
{
|
|
private k_Iterator mk_Begin, mk_End;
|
|
private int mi_Count;
|
|
|
|
public k_CollectionOnIterators(k_Iterator ak_Begin, k_Iterator ak_End)
|
|
{
|
|
mk_Begin = ak_Begin;
|
|
mk_End = ak_End;
|
|
mi_Count = mk_End - mk_Begin;
|
|
}
|
|
|
|
#region ICollection Members
|
|
|
|
public int Count
|
|
{
|
|
get { return mi_Count; }
|
|
}
|
|
|
|
public bool IsSynchronized
|
|
{
|
|
get { return false; }
|
|
}
|
|
|
|
public object SyncRoot
|
|
{
|
|
get { return mk_Begin.Collection; }
|
|
}
|
|
|
|
public void CopyTo(Array ak_Array, int ai_Index)
|
|
{
|
|
foreach (object lk_Obj in this)
|
|
ak_Array.SetValue(lk_Obj, ai_Index++);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IEnumerable Members
|
|
|
|
public IEnumerator GetEnumerator()
|
|
{
|
|
return new k_IteratorEnumerator(mk_Begin, mk_End);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
[Serializable]
|
|
public class k_IteratorPinnedException : InvalidOperationException
|
|
{
|
|
public k_IteratorPinnedException()
|
|
: base("Cannot move pinned iterator. Use Clone() to create a movable copy.")
|
|
{
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class k_InvalidPositionException : InvalidOperationException
|
|
{
|
|
public k_InvalidPositionException()
|
|
: base("Iterator positioned on End or invalid element.")
|
|
{
|
|
}
|
|
}
|
|
}
|