/*
Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Text;
using System.Diagnostics;
using SCG = System.Collections.Generic;
namespace C5
{
///
/// An advanced interface to operations on an array. The array is viewed as an
/// of fixed size, and so all operations that would change the
/// size of the array will be invalid (and throw
///
///
public class WrappedArray : IList, SCG.IList
{
class InnerList : ArrayList
{
internal InnerList(T[] array) { this.array = array; size = array.Length; }
}
ArrayList innerlist;
//TODO: remember a ref to the wrapped array in WrappedArray to save a little on indexing?
WrappedArray underlying;
///
///
///
///
public WrappedArray(T[] wrappedarray) { innerlist = new InnerList(wrappedarray); }
//for views
WrappedArray(ArrayList arraylist, WrappedArray underlying) { innerlist = arraylist; this.underlying = underlying; }
#region IList Members
///
///
///
///
public T First { get { return innerlist.First; } }
///
///
///
///
public T Last { get { return innerlist.Last; } }
///
///
///
///
///
public T this[int index]
{
get { return innerlist[index]; }
set { innerlist[index] = value; }
}
///
///
///
///
///
public IList FindAll(Fun filter) { return innerlist.FindAll(filter); }
///
///
///
///
///
///
public IList Map(Fun mapper) { return innerlist.Map(mapper); }
///
///
///
///
///
///
///
public IList Map(Fun mapper, SCG.IEqualityComparer equalityComparer) { return innerlist.Map(mapper, equalityComparer); }
///
/// ???? should we throw NotRelevantException
///
///
public bool FIFO
{
get { throw new FixedSizeCollectionException(); }
set { throw new FixedSizeCollectionException(); }
}
///
///
///
public virtual bool IsFixedSize
{
get { return true; }
}
///
///
///
///
///
public void Insert(int index, T item)
{
throw new FixedSizeCollectionException();
}
///
///
///
///
///
public void Insert(IList pointer, T item)
{
throw new FixedSizeCollectionException();
}
///
///
///
///
public void InsertFirst(T item)
{
throw new FixedSizeCollectionException();
}
///
///
///
///
public void InsertLast(T item)
{
throw new FixedSizeCollectionException();
}
///
///
///
///
///
///
public void InsertAll(int i, System.Collections.Generic.IEnumerable items) where U : T
{
throw new FixedSizeCollectionException();
}
///
///
///
///
public T Remove()
{
throw new FixedSizeCollectionException();
}
///
///
///
///
public T RemoveFirst()
{
throw new FixedSizeCollectionException();
}
///
///
///
///
public T RemoveLast()
{
throw new FixedSizeCollectionException();
}
///
///
///
///
///
///
public IList View(int start, int count)
{
return new WrappedArray((ArrayList)innerlist.View(start, count), underlying ?? this);
}
///
///
///
///
///
public IList ViewOf(T item)
{
return new WrappedArray((ArrayList)innerlist.ViewOf(item), underlying ?? this);
}
///
///
///
///
///
public IList LastViewOf(T item)
{
return new WrappedArray((ArrayList)innerlist.LastViewOf(item), underlying ?? this);
}
///
///
///
///
public IList Underlying { get { return underlying; } }
///
///
///
///
public int Offset { get { return innerlist.Offset; } }
///
///
///
///
public bool IsValid { get { return innerlist.IsValid; } }
///
///
///
///
///
public IList Slide(int offset) { return innerlist.Slide(offset); }
///
///
///
///
///
///
public IList Slide(int offset, int size) { return innerlist.Slide(offset, size); }
///
///
///
///
///
public bool TrySlide(int offset) { return innerlist.TrySlide(offset); }
///
///
///
///
///
///
public bool TrySlide(int offset, int size) { return innerlist.TrySlide(offset, size); }
///
///
///
///
///
public IList Span(IList otherView) { return innerlist.Span(((WrappedArray)otherView).innerlist); }
///
///
///
public void Reverse() { innerlist.Reverse(); }
///
///
///
///
public bool IsSorted() { return innerlist.IsSorted(); }
///
///
///
///
///
public bool IsSorted(SCG.IComparer comparer) { return innerlist.IsSorted(comparer); }
///
///
///
public void Sort() { innerlist.Sort(); }
///
///
///
///
public void Sort(SCG.IComparer comparer) { innerlist.Sort(comparer); }
///
///
///
public void Shuffle() { innerlist.Shuffle(); }
///
///
///
///
public void Shuffle(Random rnd) { innerlist.Shuffle(rnd); }
#endregion
#region IIndexed Members
///
///
///
///
public Speed IndexingSpeed { get { return Speed.Constant; } }
///
///
///
///
///
///
public IDirectedCollectionValue this[int start, int count] { get { return innerlist[start, count]; } }
///
///
///
///
///
public int IndexOf(T item) { return innerlist.IndexOf(item); }
///
///
///
///
///
public int LastIndexOf(T item) { return innerlist.LastIndexOf(item); }
///
///
///
///
///
public int FindIndex(Fun predicate) { return innerlist.FindIndex(predicate); }
///
///
///
///
///
public int FindLastIndex(Fun predicate) { return innerlist.FindLastIndex(predicate); }
///
///
///
///
///
public T RemoveAt(int i) { throw new FixedSizeCollectionException(); }
///
///
///
///
///
public void RemoveInterval(int start, int count) { throw new FixedSizeCollectionException(); }
#endregion
#region ISequenced Members
///
///
///
///
public int GetSequencedHashCode() { return innerlist.GetSequencedHashCode(); }
///
///
///
///
///
public bool SequencedEquals(ISequenced that) { return innerlist.SequencedEquals(that); }
#endregion
#region ICollection Members
///
///
///
///
public Speed ContainsSpeed { get { return Speed.Linear; } }
///
///
///
///
public int GetUnsequencedHashCode() { return innerlist.GetUnsequencedHashCode(); }
///
///
///
///
///
public bool UnsequencedEquals(ICollection that) { return innerlist.UnsequencedEquals(that); }
///
///
///
///
///
public bool Contains(T item) { return innerlist.Contains(item); }
///
///
///
///
///
public int ContainsCount(T item) { return innerlist.ContainsCount(item); }
///
///
///
///
public ICollectionValue UniqueItems() { return innerlist.UniqueItems(); }
///
///
///
///
public ICollectionValue> ItemMultiplicities() { return innerlist.ItemMultiplicities(); }
///
///
///
///
///
///
public bool ContainsAll(System.Collections.Generic.IEnumerable items) where U : T
{ return innerlist.ContainsAll(items); }
///
///
///
///
///
public bool Find(ref T item) { return innerlist.Find(ref item); }
///
///
///
///
///
public bool FindOrAdd(ref T item) { throw new FixedSizeCollectionException(); }
///
///
///
///
///
public bool Update(T item) { throw new FixedSizeCollectionException(); }
///
///
///
///
///
///
public bool Update(T item, out T olditem) { throw new FixedSizeCollectionException(); }
///
///
///
///
///
public bool UpdateOrAdd(T item) { throw new FixedSizeCollectionException(); }
///
///
///
///
///
///
public bool UpdateOrAdd(T item, out T olditem) { throw new FixedSizeCollectionException(); }
///
///
///
///
///
public bool Remove(T item) { throw new FixedSizeCollectionException(); }
///
///
///
///
///
///
public bool Remove(T item, out T removeditem) { throw new FixedSizeCollectionException(); }
///
///
///
///
public void RemoveAllCopies(T item) { throw new FixedSizeCollectionException(); }
///
///
///
///
///
public void RemoveAll(System.Collections.Generic.IEnumerable items) where U : T { throw new FixedSizeCollectionException(); }
///
///
///
public void Clear() { throw new FixedSizeCollectionException(); }
///
///
///
///
///
public void RetainAll(System.Collections.Generic.IEnumerable items) where U : T { throw new FixedSizeCollectionException(); }
#endregion
#region IExtensible Members
///
///
///
///
public bool IsReadOnly { get { return true; } }
///
///
///
///
public bool AllowsDuplicates
{
get { return true; }
}
///
///
///
///
public SCG.IEqualityComparer EqualityComparer { get { return innerlist.EqualityComparer; } }
///
///
///
///
public bool DuplicatesByCounting
{
get { return false; }
}
///
///
///
///
///
public bool Add(T item)
{
throw new FixedSizeCollectionException();
}
///
///
///
///
///
public void AddAll(System.Collections.Generic.IEnumerable items) where U : T
{
throw new FixedSizeCollectionException();
}
///
///
///
///
public bool Check()
{
return innerlist.Check() && (underlying == null || underlying.innerlist == innerlist.Underlying);
}
#endregion
#region ICollectionValue Members
///
/// No listeners may be installed
///
/// 0
public virtual EventTypeEnum ListenableEvents { get { return 0; } }
///
/// No listeners ever installed
///
/// 0
public virtual EventTypeEnum ActiveEvents { get { return 0; } }
///
///
///
///
public event CollectionChangedHandler CollectionChanged
{
add { throw new UnlistenableEventException(); }
remove { throw new UnlistenableEventException(); }
}
///
///
///
///
public event CollectionClearedHandler CollectionCleared
{
add { throw new UnlistenableEventException(); }
remove { throw new UnlistenableEventException(); }
}
///
///
///
///
public event ItemsAddedHandler ItemsAdded
{
add { throw new UnlistenableEventException(); }
remove { throw new UnlistenableEventException(); }
}
///
///
///
///
public event ItemInsertedHandler ItemInserted
{
add { throw new UnlistenableEventException(); }
remove { throw new UnlistenableEventException(); }
}
///
///
///
///
public event ItemsRemovedHandler ItemsRemoved
{
add { throw new UnlistenableEventException(); }
remove { throw new UnlistenableEventException(); }
}
///
///
///
///
public event ItemRemovedAtHandler ItemRemovedAt
{
add { throw new UnlistenableEventException(); }
remove { throw new UnlistenableEventException(); }
}
///
///
///
///
public bool IsEmpty { get { return innerlist.IsEmpty; } }
///
///
///
///
public int Count { get { return innerlist.Count; } }
///
///
///
///
public Speed CountSpeed { get { return innerlist.CountSpeed; } }
///
///
///
///
///
public void CopyTo(T[] array, int index) { innerlist.CopyTo(array, index); }
///
///
///
///
public T[] ToArray() { return innerlist.ToArray(); }
///
///
///
///
public void Apply(Act action) { innerlist.Apply(action); }
///
///
///
///
///
public bool Exists(Fun predicate) { return innerlist.Exists(predicate); }
///
///
///
///
///
///
public bool Find(Fun predicate, out T item) { return innerlist.Find(predicate, out item); }
///
///
///
///
///
public bool All(Fun predicate) { return innerlist.All(predicate); }
///
///
///
///
public T Choose() { return innerlist.Choose(); }
///
///
///
///
///
public SCG.IEnumerable Filter(Fun filter) { return innerlist.Filter(filter); }
#endregion
#region IEnumerable Members
///
///
///
///
public SCG.IEnumerator GetEnumerator() { return innerlist.GetEnumerator(); }
#endregion
#region IShowable Members
///
///
///
///
///
///
///
public bool Show(StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
{ return innerlist.Show(stringbuilder, ref rest, formatProvider); }
#endregion
#region IFormattable Members
///
///
///
///
public override string ToString() { return innerlist.ToString(); }
///
///
///
///
///
///
public virtual string ToString(string format, IFormatProvider formatProvider) { return innerlist.ToString(format, formatProvider); }
#endregion
#region IDirectedCollectionValue Members
///
///
///
///
public IDirectedCollectionValue Backwards() { return innerlist.Backwards(); }
///
///
///
///
///
///
public bool FindLast(Fun predicate, out T item) { return innerlist.FindLast(predicate, out item); }
#endregion
#region IDirectedEnumerable Members
IDirectedEnumerable IDirectedEnumerable.Backwards() { return Backwards(); }
///
///
///
///
public EnumerationDirection Direction { get { return EnumerationDirection.Forwards; } }
#endregion
#region IDisposable Members
///
/// Dispose this if a view else operation is illegal
///
/// If not a view
public void Dispose()
{
if (underlying == null)
throw new FixedSizeCollectionException();
else
innerlist.Dispose();
}
#endregion
#region ICloneable Members
///
/// Make a shallow copy of this WrappedArray.
///
///
///
///
public virtual object Clone()
{
return new WrappedArray(innerlist.ToArray());
}
#endregion
#region System.Collections.Generic.IList Members
void System.Collections.Generic.IList.RemoveAt(int index)
{
throw new FixedSizeCollectionException();
}
void System.Collections.Generic.ICollection.Add(T item)
{
throw new FixedSizeCollectionException();
}
#endregion
#region System.Collections.ICollection Members
bool System.Collections.ICollection.IsSynchronized
{
get { return false; }
}
[Obsolete]
Object System.Collections.ICollection.SyncRoot
{
get { return ((System.Collections.IList)innerlist).SyncRoot; }
}
void System.Collections.ICollection.CopyTo(Array arr, int index)
{
if (index < 0 || index + Count > arr.Length)
throw new ArgumentOutOfRangeException();
foreach (T item in this)
arr.SetValue(item, index++);
}
#endregion
#region System.Collections.IList Members
Object System.Collections.IList.this[int index]
{
get { return this[index]; }
set { this[index] = (T)value; }
}
int System.Collections.IList.Add(Object o)
{
bool added = Add((T)o);
// What position to report if item not added? SC.IList.Add doesn't say
return added ? Count - 1 : -1;
}
bool System.Collections.IList.Contains(Object o)
{
return Contains((T)o);
}
int System.Collections.IList.IndexOf(Object o)
{
return Math.Max(-1, IndexOf((T)o));
}
void System.Collections.IList.Insert(int index, Object o)
{
Insert(index, (T)o);
}
void System.Collections.IList.Remove(Object o)
{
Remove((T)o);
}
void System.Collections.IList.RemoveAt(int index)
{
RemoveAt(index);
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new Exception("The method or operation is not implemented.");
}
#endregion
}
}