/mcs/class/Mono.C5/C5/Wrappers.cs
C# | 2405 lines | 770 code | 484 blank | 1151 comment | 33 complexity | 9ac782af976065aa2abfdd264317fd29 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- 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.Diagnostics;
- using SCG = System.Collections.Generic;
- namespace C5
- {
- /// <summary>
- /// A read-only wrapper class for a generic enumerator
- /// </summary>
- public class GuardedEnumerator<T> : SCG.IEnumerator<T>
- {
- #region Fields
- SCG.IEnumerator<T> enumerator;
- #endregion
- #region Constructor
- /// <summary>
- /// Create a wrapper around a generic enumerator
- /// </summary>
- /// <param name="enumerator">The enumerator to wrap</param>
- public GuardedEnumerator(SCG.IEnumerator<T> enumerator)
- { this.enumerator = enumerator; }
- #endregion
- #region IEnumerator<T> Members
- /// <summary>
- /// Move wrapped enumerator to next item, or the first item if
- /// this is the first call to MoveNext.
- /// </summary>
- /// <returns>True if enumerator is valid now</returns>
- public bool MoveNext() { return enumerator.MoveNext(); }
- /// <summary>
- /// Undefined if enumerator is not valid (MoveNext hash been called returning true)
- /// </summary>
- /// <value>The current item of the wrapped enumerator.</value>
- public T Current { get { return enumerator.Current; } }
- #endregion
- #region IDisposable Members
- //TODO: consider possible danger of calling through to Dispose.
- /// <summary>
- /// Dispose wrapped enumerator.
- /// </summary>
- public void Dispose() { enumerator.Dispose(); }
- #endregion
- #region IEnumerator Members
- object System.Collections.IEnumerator.Current
- {
- get { return enumerator.Current; }
- }
- void System.Collections.IEnumerator.Reset()
- {
- enumerator.Reset();
- }
- #endregion
- }
- /// <summary>
- /// A read-only wrapper class for a generic enumerable
- ///
- /// <i>This is mainly interesting as a base of other guard classes</i>
- /// </summary>
- public class GuardedEnumerable<T> : SCG.IEnumerable<T>
- {
- #region Fields
- SCG.IEnumerable<T> enumerable;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap an enumerable in a read-only wrapper
- /// </summary>
- /// <param name="enumerable">The enumerable to wrap</param>
- public GuardedEnumerable(SCG.IEnumerable<T> enumerable)
- { this.enumerable = enumerable; }
- #endregion
- #region SCG.IEnumerable<T> Members
- /// <summary>
- /// Get an enumerator from the wrapped enumerable
- /// </summary>
- /// <returns>The enumerator (itself wrapped)</returns>
- public SCG.IEnumerator<T> GetEnumerator()
- { return new GuardedEnumerator<T>(enumerable.GetEnumerator()); }
- #endregion
- #region IEnumerable Members
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- #endregion
- }
- /// <summary>
- /// A read-only wrapper for a generic directed enumerable
- ///
- /// <i>This is mainly interesting as a base of other guard classes</i>
- /// </summary>
- public class GuardedDirectedEnumerable<T> : GuardedEnumerable<T>, IDirectedEnumerable<T>
- {
- #region Fields
- IDirectedEnumerable<T> directedenumerable;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap a directed enumerable in a read-only wrapper
- /// </summary>
- /// <param name="directedenumerable">the collection to wrap</param>
- public GuardedDirectedEnumerable(IDirectedEnumerable<T> directedenumerable)
- : base(directedenumerable)
- { this.directedenumerable = directedenumerable; }
- #endregion
- #region IDirectedEnumerable<T> Members
- /// <summary>
- /// Get a enumerable that enumerates the wrapped collection in the opposite direction
- /// </summary>
- /// <returns>The mirrored enumerable</returns>
- public IDirectedEnumerable<T> Backwards()
- { return new GuardedDirectedEnumerable<T>(directedenumerable.Backwards()); }
- /// <summary>
- /// <code>Forwards</code> if same, else <code>Backwards</code>
- /// </summary>
- /// <value>The enumeration direction relative to the original collection.</value>
- public EnumerationDirection Direction
- { get { return directedenumerable.Direction; } }
- #endregion
- }
- /// <summary>
- /// A read-only wrapper for an ICollectionValue<T>
- ///
- /// <i>This is mainly interesting as a base of other guard classes</i>
- /// </summary>
- public class GuardedCollectionValue<T> : GuardedEnumerable<T>, ICollectionValue<T>
- {
- #region Events
- /// <summary>
- /// The ListenableEvents value of the wrapped collection
- /// </summary>
- /// <value></value>
- public virtual EventTypeEnum ListenableEvents { get { return collectionvalue.ListenableEvents; } }
- /// <summary>
- /// The ActiveEvents value of the wrapped collection
- /// </summary>
- /// <value></value>
- public virtual EventTypeEnum ActiveEvents { get { return collectionvalue.ActiveEvents; } }
- ProxyEventBlock<T> eventBlock;
- /// <summary>
- /// The change event. Will be raised for every change operation on the collection.
- /// </summary>
- public event CollectionChangedHandler<T> CollectionChanged
- {
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).CollectionChanged += value; }
- remove { if (eventBlock != null) eventBlock.CollectionChanged -= value; }
- }
- /// <summary>
- /// The change event. Will be raised for every change operation on the collection.
- /// </summary>
- public event CollectionClearedHandler<T> CollectionCleared
- {
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).CollectionCleared += value; }
- remove { if (eventBlock != null) eventBlock.CollectionCleared -= value; }
- }
- /// <summary>
- /// The item added event. Will be raised for every individual addition to the collection.
- /// </summary>
- public event ItemsAddedHandler<T> ItemsAdded
- {
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemsAdded += value; }
- remove { if (eventBlock != null) eventBlock.ItemsAdded -= value; }
- }
- /// <summary>
- /// The item added event. Will be raised for every individual addition to the collection.
- /// </summary>
- public event ItemInsertedHandler<T> ItemInserted
- {
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemInserted += value; }
- remove { if (eventBlock != null) eventBlock.ItemInserted -= value; }
- }
- /// <summary>
- /// The item removed event. Will be raised for every individual removal from the collection.
- /// </summary>
- public event ItemsRemovedHandler<T> ItemsRemoved
- {
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemsRemoved += value; }
- remove { if (eventBlock != null) eventBlock.ItemsRemoved -= value; }
- }
- /// <summary>
- /// The item removed event. Will be raised for every individual removal from the collection.
- /// </summary>
- public event ItemRemovedAtHandler<T> ItemRemovedAt
- {
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemRemovedAt += value; }
- remove { if (eventBlock != null) eventBlock.ItemRemovedAt -= value; }
- }
- #endregion
- #region Fields
- ICollectionValue<T> collectionvalue;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap a ICollectionValue<T> in a read-only wrapper
- /// </summary>
- /// <param name="collectionvalue">the collection to wrap</param>
- public GuardedCollectionValue(ICollectionValue<T> collectionvalue)
- : base(collectionvalue)
- { this.collectionvalue = collectionvalue; }
- #endregion
- #region ICollection<T> Members
- /// <summary>
- /// Get the size of the wrapped collection
- /// </summary>
- /// <value>The size</value>
- public virtual bool IsEmpty { get { return collectionvalue.IsEmpty; } }
- /// <summary>
- /// Get the size of the wrapped collection
- /// </summary>
- /// <value>The size</value>
- public virtual int Count { get { return collectionvalue.Count; } }
- /// <summary>
- /// The value is symbolic indicating the type of asymptotic complexity
- /// in terms of the size of this collection (worst-case or amortized as
- /// relevant).
- /// </summary>
- /// <value>A characterization of the speed of the
- /// <code>Count</code> property in this collection.</value>
- public virtual Speed CountSpeed { get { return collectionvalue.CountSpeed; } }
- /// <summary>
- /// Copy the items of the wrapped collection to an array
- /// </summary>
- /// <param name="a">The array</param>
- /// <param name="i">Starting offset</param>
- public virtual void CopyTo(T[] a, int i) { collectionvalue.CopyTo(a, i); }
- /// <summary>
- /// Create an array from the items of the wrapped collection
- /// </summary>
- /// <returns>The array</returns>
- public virtual T[] ToArray() { return collectionvalue.ToArray(); }
- /// <summary>
- /// Apply a delegate to all items of the wrapped enumerable.
- /// </summary>
- /// <param name="a">The delegate to apply</param>
- //TODO: change this to throw an exception?
- public virtual void Apply(Act<T> a) { collectionvalue.Apply(a); }
- /// <summary>
- /// Check if there exists an item that satisfies a
- /// specific predicate in the wrapped enumerable.
- /// </summary>
- /// <param name="filter">A filter delegate
- /// (<see cref="T:C5.Filter`1"/>) defining the predicate</param>
- /// <returns>True is such an item exists</returns>
- public virtual bool Exists(Fun<T, bool> filter) { return collectionvalue.Exists(filter); }
- /// <summary>
- ///
- /// </summary>
- /// <param name="filter"></param>
- /// <param name="item"></param>
- /// <returns></returns>
- public virtual bool Find(Fun<T, bool> filter, out T item) { return collectionvalue.Find(filter, out item); }
- /// <summary>
- /// Check if all items in the wrapped enumerable satisfies a specific predicate.
- /// </summary>
- /// <param name="filter">A filter delegate
- /// (<see cref="T:C5.Filter`1"/>) defining the predicate</param>
- /// <returns>True if all items satisfies the predicate</returns>
- public virtual bool All(Fun<T, bool> filter) { return collectionvalue.All(filter); }
- /// <summary>
- /// Create an enumerable, enumerating the items of this collection that satisfies
- /// a certain condition.
- /// </summary>
- /// <param name="filter">The T->bool filter delegate defining the condition</param>
- /// <returns>The filtered enumerable</returns>
- public virtual SCG.IEnumerable<T> Filter(Fun<T, bool> filter) { return collectionvalue.Filter(filter); }
- /// <summary>
- /// Choose some item of this collection.
- /// </summary>
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>
- /// <returns></returns>
- public virtual T Choose() { return collectionvalue.Choose(); }
- #endregion
- #region IShowable Members
- /// <summary>
- ///
- /// </summary>
- /// <param name="stringbuilder"></param>
- /// <param name="formatProvider"></param>
- /// <param name="rest"></param>
- /// <returns></returns>
- public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
- {
- return collectionvalue.Show(stringbuilder, ref rest, formatProvider);
- }
- #endregion
- #region IFormattable Members
- /// <summary>
- ///
- /// </summary>
- /// <param name="format"></param>
- /// <param name="formatProvider"></param>
- /// <returns></returns>
- public string ToString(string format, IFormatProvider formatProvider)
- {
- return collectionvalue.ToString(format, formatProvider);
- }
- #endregion
- }
- /// <summary>
- /// A read-only wrapper for a directed collection
- ///
- /// <i>This is mainly interesting as a base of other guard classes</i>
- /// </summary>
- public class GuardedDirectedCollectionValue<T> : GuardedCollectionValue<T>, IDirectedCollectionValue<T>
- {
- #region Fields
- IDirectedCollectionValue<T> directedcollection;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap a directed collection in a read-only wrapper
- /// </summary>
- /// <param name="directedcollection">the collection to wrap</param>
- public GuardedDirectedCollectionValue(IDirectedCollectionValue<T> directedcollection)
- :
- base(directedcollection)
- { this.directedcollection = directedcollection; }
- #endregion
- #region IDirectedCollection<T> Members
- /// <summary>
- /// Get a collection that enumerates the wrapped collection in the opposite direction
- /// </summary>
- /// <returns>The mirrored collection</returns>
- public virtual IDirectedCollectionValue<T> Backwards()
- { return new GuardedDirectedCollectionValue<T>(directedcollection.Backwards()); }
- /// <summary>
- ///
- /// </summary>
- /// <param name="predicate"></param>
- /// <param name="item"></param>
- /// <returns></returns>
- public virtual bool FindLast(Fun<T, bool> predicate, out T item) { return directedcollection.FindLast(predicate, out item); }
- #endregion
- #region IDirectedEnumerable<T> Members
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()
- { return Backwards(); }
- /// <summary>
- /// <code>Forwards</code> if same, else <code>Backwards</code>
- /// </summary>
- /// <value>The enumeration direction relative to the original collection.</value>
- public EnumerationDirection Direction
- { get { return directedcollection.Direction; } }
- #endregion
- }
- /// <summary>
- /// A read-only wrapper for an <see cref="T:C5.ICollection`1"/>,
- /// <para>
- /// <i>Suitable for wrapping hash tables, <see cref="T:C5.HashSet`1"/>
- /// and <see cref="T:C5.HashBag`1"/> </i></para>
- /// </summary>
- public class GuardedCollection<T> : GuardedCollectionValue<T>, ICollection<T>
- {
- #region Fields
- ICollection<T> collection;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap an ICollection<T> in a read-only wrapper
- /// </summary>
- /// <param name="collection">the collection to wrap</param>
- public GuardedCollection(ICollection<T> collection)
- : base(collection)
- {
- this.collection = collection;
- }
- #endregion
- #region ICollection<T> Members
- /// <summary>
- /// (This is a read-only wrapper)
- /// </summary>
- /// <value>True</value>
- public virtual bool IsReadOnly { get { return true; } }
- /// <summary> </summary>
- /// <value>Speed of wrapped collection</value>
- public virtual Speed ContainsSpeed { get { return collection.ContainsSpeed; } }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public virtual int GetUnsequencedHashCode()
- { return collection.GetUnsequencedHashCode(); }
- /// <summary>
- ///
- /// </summary>
- /// <param name="that"></param>
- /// <returns></returns>
- public virtual bool UnsequencedEquals(ICollection<T> that)
- { return collection.UnsequencedEquals(that); }
- /// <summary>
- /// Check if an item is in the wrapped collection
- /// </summary>
- /// <param name="item">The item</param>
- /// <returns>True if found</returns>
- public virtual bool Contains(T item) { return collection.Contains(item); }
- /// <summary>
- /// Count the number of times an item appears in the wrapped collection
- /// </summary>
- /// <param name="item">The item</param>
- /// <returns>The number of copies</returns>
- public virtual int ContainsCount(T item) { return collection.ContainsCount(item); }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public virtual ICollectionValue<T> UniqueItems() { return new GuardedCollectionValue<T>(collection.UniqueItems()); }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities() { return new GuardedCollectionValue<KeyValuePair<T, int>>(collection.ItemMultiplicities()); }
- /// <summary>
- /// Check if all items in the argument is in the wrapped collection
- /// </summary>
- /// <param name="items">The items</param>
- /// <typeparam name="U"></typeparam>
- /// <returns>True if so</returns>
- public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T { return collection.ContainsAll(items); }
- /// <summary>
- /// Search for an item in the wrapped collection
- /// </summary>
- /// <param name="item">On entry the item to look for, on exit the equivalent item found (if any)</param>
- /// <returns></returns>
- public virtual bool Find(ref T item) { return collection.Find(ref item); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <returns></returns>
- public virtual bool FindOrAdd(ref T item)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <returns></returns>
- public virtual bool Update(T item)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <param name="olditem"></param>
- /// <returns></returns>
- public virtual bool Update(T item, out T olditem)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <returns></returns>
- public virtual bool UpdateOrAdd(T item)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <param name="olditem"></param>
- /// <returns></returns>
- public virtual bool UpdateOrAdd(T item, out T olditem)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <returns></returns>
- public virtual bool Remove(T item)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item">The value to remove.</param>
- /// <param name="removeditem">The removed value.</param>
- /// <returns></returns>
- public virtual bool Remove(T item, out T removeditem)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- public virtual void RemoveAllCopies(T item)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <typeparam name="U"></typeparam>
- /// <param name="items"></param>
- public virtual void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- public virtual void Clear()
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <typeparam name="U"></typeparam>
- /// <param name="items"></param>
- public virtual void RetainAll<U>(SCG.IEnumerable<U> items) where U : T
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// Check wrapped collection for internal consistency
- /// </summary>
- /// <returns>True if check passed</returns>
- public virtual bool Check() { return collection.Check(); }
- #endregion
- #region IExtensible<T> Members
- /// <summary> </summary>
- /// <value>False if wrapped collection has set semantics</value>
- public virtual bool AllowsDuplicates { get { return collection.AllowsDuplicates; } }
- //TODO: the equalityComparer should be guarded
- /// <summary>
- ///
- /// </summary>
- /// <value></value>
- public virtual SCG.IEqualityComparer<T> EqualityComparer { get { return collection.EqualityComparer; } }
- /// <summary>
- /// By convention this is true for any collection with set semantics.
- /// </summary>
- /// <value>True if only one representative of a group of equal items
- /// is kept in the collection together with the total count.</value>
- public virtual bool DuplicatesByCounting { get { return collection.DuplicatesByCounting; } }
- /// <summary> </summary>
- /// <value>True if wrapped collection is empty</value>
- public override bool IsEmpty { get { return collection.IsEmpty; } }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <returns></returns>
- public virtual bool Add(T item)
- { throw new ReadOnlyCollectionException(); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- void SCG.ICollection<T>.Add(T item)
- { throw new ReadOnlyCollectionException(); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <typeparam name="U"></typeparam>
- /// <param name="items"></param>
- public virtual void AddAll<U>(SCG.IEnumerable<U> items) where U : T
- { throw new ReadOnlyCollectionException(); }
- #endregion
- #region ICloneable Members
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public virtual object Clone()
- {
- return new GuardedCollection<T>((ICollection<T>)(collection.Clone()));
- }
- #endregion
- }
- /// <summary>
- /// A read-only wrapper for a sequenced collection
- ///
- /// <i>This is mainly interesting as a base of other guard classes</i>
- /// </summary>
- public class GuardedSequenced<T> : GuardedCollection<T>, ISequenced<T>
- {
- #region Fields
- ISequenced<T> sequenced;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap a sequenced collection in a read-only wrapper
- /// </summary>
- /// <param name="sorted"></param>
- public GuardedSequenced(ISequenced<T> sorted) : base(sorted) { this.sequenced = sorted; }
- #endregion
- /// <summary>
- /// Check if there exists an item that satisfies a
- /// specific predicate in this collection and return the index of the first one.
- /// </summary>
- /// <param name="predicate">A delegate
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>
- /// <returns>the index, if found, a negative value else</returns>
- public int FindIndex(Fun<T, bool> predicate)
- {
- IIndexed<T> indexed = sequenced as IIndexed<T>;
- if (indexed != null)
- return indexed.FindIndex(predicate);
- int index = 0;
- foreach (T item in this)
- {
- if (predicate(item))
- return index;
- index++;
- }
- return -1;
- }
- /// <summary>
- /// Check if there exists an item that satisfies a
- /// specific predicate in this collection and return the index of the last one.
- /// </summary>
- /// <param name="predicate">A delegate
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>
- /// <returns>the index, if found, a negative value else</returns>
- public int FindLastIndex(Fun<T, bool> predicate)
- {
- IIndexed<T> indexed = sequenced as IIndexed<T>;
- if (indexed != null)
- return indexed.FindLastIndex(predicate);
- int index = Count - 1;
- foreach (T item in Backwards())
- {
- if (predicate(item))
- return index;
- index--;
- }
- return -1;
- }
- #region ISequenced<T> Members
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public int GetSequencedHashCode()
- { return sequenced.GetSequencedHashCode(); }
- /// <summary>
- ///
- /// </summary>
- /// <param name="that"></param>
- /// <returns></returns>
- public bool SequencedEquals(ISequenced<T> that)
- { return sequenced.SequencedEquals(that); }
- #endregion
- #region IDirectedCollection<T> Members
- /// <summary>
- /// Get a collection that enumerates the wrapped collection in the opposite direction
- /// </summary>
- /// <returns>The mirrored collection</returns>
- public virtual IDirectedCollectionValue<T> Backwards()
- { return new GuardedDirectedCollectionValue<T>(sequenced.Backwards()); }
- /// <summary>
- ///
- /// </summary>
- /// <param name="predicate"></param>
- /// <param name="item"></param>
- /// <returns></returns>
- public virtual bool FindLast(Fun<T, bool> predicate, out T item) { return sequenced.FindLast(predicate, out item); }
- #endregion
- #region IDirectedEnumerable<T> Members
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()
- { return Backwards(); }
- /// <summary>
- /// <code>Forwards</code> if same, else <code>Backwards</code>
- /// </summary>
- /// <value>The enumeration direction relative to the original collection.</value>
- public EnumerationDirection Direction
- { get { return EnumerationDirection.Forwards; } }
- #endregion
- #region ICloneable Members
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public override object Clone()
- {
- return new GuardedCollection<T>((ISequenced<T>)(sequenced.Clone()));
- }
- #endregion
- }
- /// <summary>
- /// A read-only wrapper for a sorted collection
- ///
- /// <i>This is mainly interesting as a base of other guard classes</i>
- /// </summary>
- public class GuardedSorted<T> : GuardedSequenced<T>, ISorted<T>
- {
- #region Fields
- ISorted<T> sorted;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap a sorted collection in a read-only wrapper
- /// </summary>
- /// <param name="sorted"></param>
- public GuardedSorted(ISorted<T> sorted) : base(sorted) { this.sorted = sorted; }
- #endregion
- #region ISorted<T> Members
- /// <summary>
- /// Find the strict predecessor of item in the guarded sorted collection,
- /// that is, the greatest item in the collection smaller than the item.
- /// </summary>
- /// <param name="item">The item to find the predecessor for.</param>
- /// <param name="res">The predecessor, if any; otherwise the default value for T.</param>
- /// <returns>True if item has a predecessor; otherwise false.</returns>
- public bool TryPredecessor(T item, out T res) { return sorted.TryPredecessor(item, out res); }
- /// <summary>
- /// Find the strict successor of item in the guarded sorted collection,
- /// that is, the least item in the collection greater than the supplied value.
- /// </summary>
- /// <param name="item">The item to find the successor for.</param>
- /// <param name="res">The successor, if any; otherwise the default value for T.</param>
- /// <returns>True if item has a successor; otherwise false.</returns>
- public bool TrySuccessor(T item, out T res) { return sorted.TrySuccessor(item, out res); }
- /// <summary>
- /// Find the weak predecessor of item in the guarded sorted collection,
- /// that is, the greatest item in the collection smaller than or equal to the item.
- /// </summary>
- /// <param name="item">The item to find the weak predecessor for.</param>
- /// <param name="res">The weak predecessor, if any; otherwise the default value for T.</param>
- /// <returns>True if item has a weak predecessor; otherwise false.</returns>
- public bool TryWeakPredecessor(T item, out T res) { return sorted.TryWeakPredecessor(item, out res); }
- /// <summary>
- /// Find the weak successor of item in the sorted collection,
- /// that is, the least item in the collection greater than or equal to the supplied value.
- /// </summary>
- /// <param name="item">The item to find the weak successor for.</param>
- /// <param name="res">The weak successor, if any; otherwise the default value for T.</param>
- /// <returns>True if item has a weak successor; otherwise false.</returns>
- public bool TryWeakSuccessor(T item, out T res) { return sorted.TryWeakSuccessor(item, out res); }
- /// <summary>
- /// Find the predecessor of the item in the wrapped sorted collection
- /// </summary>
- /// <exception cref="NoSuchItemException"> if no such element exists </exception>
- /// <param name="item">The item</param>
- /// <returns>The predecessor</returns>
- public T Predecessor(T item) { return sorted.Predecessor(item); }
- /// <summary>
- /// Find the Successor of the item in the wrapped sorted collection
- /// </summary>
- /// <exception cref="NoSuchItemException"> if no such element exists </exception>
- /// <param name="item">The item</param>
- /// <returns>The Successor</returns>
- public T Successor(T item) { return sorted.Successor(item); }
- /// <summary>
- /// Find the weak predecessor of the item in the wrapped sorted collection
- /// </summary>
- /// <exception cref="NoSuchItemException"> if no such element exists </exception>
- /// <param name="item">The item</param>
- /// <returns>The weak predecessor</returns>
- public T WeakPredecessor(T item) { return sorted.WeakPredecessor(item); }
- /// <summary>
- /// Find the weak Successor of the item in the wrapped sorted collection
- /// </summary>
- /// <exception cref="NoSuchItemException"> if no such element exists </exception>
- /// <param name="item">The item</param>
- /// <returns>The weak Successor</returns>
- public T WeakSuccessor(T item) { return sorted.WeakSuccessor(item); }
- /// <summary>
- /// Run Cut on the wrapped sorted collection
- /// </summary>
- /// <param name="c"></param>
- /// <param name="low"></param>
- /// <param name="lval"></param>
- /// <param name="high"></param>
- /// <param name="hval"></param>
- /// <returns></returns>
- public bool Cut(IComparable<T> c, out T low, out bool lval, out T high, out bool hval)
- { return sorted.Cut(c, out low, out lval, out high, out hval); }
- /// <summary>
- /// Get the specified range from the wrapped collection.
- /// (The current implementation erroneously does not wrap the result.)
- /// </summary>
- /// <param name="bot"></param>
- /// <returns></returns>
- public IDirectedEnumerable<T> RangeFrom(T bot) { return sorted.RangeFrom(bot); }
- /// <summary>
- /// Get the specified range from the wrapped collection.
- /// (The current implementation erroneously does not wrap the result.)
- /// </summary>
- /// <param name="bot"></param>
- /// <param name="top"></param>
- /// <returns></returns>
- public IDirectedEnumerable<T> RangeFromTo(T bot, T top)
- { return sorted.RangeFromTo(bot, top); }
- /// <summary>
- /// Get the specified range from the wrapped collection.
- /// (The current implementation erroneously does not wrap the result.)
- /// </summary>
- /// <param name="top"></param>
- /// <returns></returns>
- public IDirectedEnumerable<T> RangeTo(T top) { return sorted.RangeTo(top); }
- /// <summary>
- /// Get the specified range from the wrapped collection.
- /// (The current implementation erroneously does not wrap the result.)
- /// </summary>
- /// <returns></returns>
- public IDirectedCollectionValue<T> RangeAll() { return sorted.RangeAll(); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="items"></param>
- /// <typeparam name="U"></typeparam>
- public void AddSorted<U>(SCG.IEnumerable<U> items) where U : T
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="low"></param>
- public void RemoveRangeFrom(T low)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="low"></param>
- /// <param name="hi"></param>
- public void RemoveRangeFromTo(T low, T hi)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="hi"></param>
- public void RemoveRangeTo(T hi)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- #endregion
- #region IPriorityQueue<T> Members
- /// <summary>
- /// Find the minimum of the wrapped collection
- /// </summary>
- /// <returns>The minimum</returns>
- public T FindMin() { return sorted.FindMin(); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <returns></returns>
- public T DeleteMin()
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// Find the maximum of the wrapped collection
- /// </summary>
- /// <returns>The maximum</returns>
- public T FindMax() { return sorted.FindMax(); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <returns></returns>
- public T DeleteMax()
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- //TODO: we should guard the comparer!
- /// <summary>
- /// The comparer object supplied at creation time for the underlying collection
- /// </summary>
- /// <value>The comparer</value>
- public SCG.IComparer<T> Comparer { get { return sorted.Comparer; } }
- #endregion
- #region IDirectedEnumerable<T> Members
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()
- { return Backwards(); }
- #endregion
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public override object Clone()
- {
- return new GuardedSorted<T>((ISorted<T>)(sorted.Clone()));
- }
- }
- /// <summary>
- /// Read-only wrapper for indexed sorted collections
- ///
- /// <i>Suitable for wrapping TreeSet, TreeBag and SortedArray</i>
- /// </summary>
- public class GuardedIndexedSorted<T> : GuardedSorted<T>, IIndexedSorted<T>
- {
- #region Fields
- IIndexedSorted<T> indexedsorted;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap an indexed sorted collection in a read-only wrapper
- /// </summary>
- /// <param name="list">the indexed sorted collection</param>
- public GuardedIndexedSorted(IIndexedSorted<T> list)
- : base(list)
- { this.indexedsorted = list; }
- #endregion
- #region IIndexedSorted<T> Members
- /// <summary>
- /// Get the specified range from the wrapped collection.
- /// (The current implementation erroneously does not wrap the result.)
- /// </summary>
- /// <param name="bot"></param>
- /// <returns></returns>
- public new IDirectedCollectionValue<T> RangeFrom(T bot)
- { return indexedsorted.RangeFrom(bot); }
- /// <summary>
- /// Get the specified range from the wrapped collection.
- /// (The current implementation erroneously does not wrap the result.)
- /// </summary>
- /// <param name="bot"></param>
- /// <param name="top"></param>
- /// <returns></returns>
- public new IDirectedCollectionValue<T> RangeFromTo(T bot, T top)
- { return indexedsorted.RangeFromTo(bot, top); }
- /// <summary>
- /// Get the specified range from the wrapped collection.
- /// (The current implementation erroneously does not wrap the result.)
- /// </summary>
- /// <param name="top"></param>
- /// <returns></returns>
- public new IDirectedCollectionValue<T> RangeTo(T top)
- { return indexedsorted.RangeTo(top); }
- /// <summary>
- /// Report the number of items in the specified range of the wrapped collection
- /// </summary>
- /// <param name="bot"></param>
- /// <returns></returns>
- public int CountFrom(T bot) { return indexedsorted.CountFrom(bot); }
- /// <summary>
- /// Report the number of items in the specified range of the wrapped collection
- /// </summary>
- /// <param name="bot"></param>
- /// <param name="top"></param>
- /// <returns></returns>
- public int CountFromTo(T bot, T top) { return indexedsorted.CountFromTo(bot, top); }
- /// <summary>
- /// Report the number of items in the specified range of the wrapped collection
- /// </summary>
- /// <param name="top"></param>
- /// <returns></returns>
- public int CountTo(T top) { return indexedsorted.CountTo(top); }
- /// <summary>
- /// Run FindAll on the wrapped collection with the indicated filter.
- /// The result will <b>not</b> be read-only.
- /// </summary>
- /// <param name="f"></param>
- /// <returns></returns>
- public IIndexedSorted<T> FindAll(Fun<T, bool> f)
- { return indexedsorted.FindAll(f); }
- /// <summary>
- /// Run Map on the wrapped collection with the indicated mapper.
- /// The result will <b>not</b> be read-only.
- /// </summary>
- /// <param name="m"></param>
- /// <param name="c">The comparer to use in the result</param>
- /// <returns></returns>
- public IIndexedSorted<V> Map<V>(Fun<T, V> m, SCG.IComparer<V> c)
- { return indexedsorted.Map(m, c); }
- #endregion
- #region IIndexed<T> Members
- /// <summary>
- ///
- /// </summary>
- /// <value>The i'th item of the wrapped sorted collection</value>
- public T this[int i] { get { return indexedsorted[i]; } }
- /// <summary>
- ///
- /// </summary>
- /// <value></value>
- public virtual Speed IndexingSpeed { get { return indexedsorted.IndexingSpeed; } }
- /// <summary> </summary>
- /// <value>A directed collection of the items in the indicated interval of the wrapped collection</value>
- public IDirectedCollectionValue<T> this[int start, int end]
- { get { return new GuardedDirectedCollectionValue<T>(indexedsorted[start, end]); } }
- /// <summary>
- /// Find the (first) index of an item in the wrapped collection
- /// </summary>
- /// <param name="item"></param>
- /// <returns></returns>
- public int IndexOf(T item) { return indexedsorted.IndexOf(item); }
- /// <summary>
- /// Find the last index of an item in the wrapped collection
- /// </summary>
- /// <param name="item"></param>
- /// <returns></returns>
- public int LastIndexOf(T item) { return indexedsorted.LastIndexOf(item); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="i"></param>
- /// <returns></returns>
- public T RemoveAt(int i)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="start"></param>
- /// <param name="count"></param>
- public void RemoveInterval(int start, int count)
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }
- #endregion
- #region IDirectedEnumerable<T> Members
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()
- { return Backwards(); }
- #endregion
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public override object Clone()
- {
- return new GuardedIndexedSorted<T>((IIndexedSorted<T>)(indexedsorted.Clone()));
- }
- }
- /// <summary>
- /// A read-only wrapper for a generic list collection
- /// <i>Suitable as a wrapper for LinkedList, HashedLinkedList, ArrayList and HashedArray.
- /// <see cref="T:C5.LinkedList`1"/>,
- /// <see cref="T:C5.HashedLinkedList`1"/>,
- /// <see cref="T:C5.ArrayList`1"/> or
- /// <see cref="T:C5.HashedArray`1"/>.
- /// </i>
- /// </summary>
- public class GuardedList<T> : GuardedSequenced<T>, IList<T>, SCG.IList<T>
- {
- #region Fields
- IList<T> innerlist;
- GuardedList<T> underlying;
- bool slidableView = false;
- #endregion
- #region Constructor
- /// <summary>
- /// Wrap a list in a read-only wrapper. A list gets wrapped as read-only,
- /// a list view gets wrapped as read-only and non-slidable.
- /// </summary>
- /// <param name="list">The list</param>
- public GuardedList(IList<T> list)
- : base(list)
- {
- this.innerlist = list;
- // If wrapping a list view, make innerlist = the view, and make
- // underlying = a guarded version of the view's underlying list
- if (list.Underlying != null)
- underlying = new GuardedList<T>(list.Underlying, null, false);
- }
- GuardedList(IList<T> list, GuardedList<T> underlying, bool slidableView)
- : base(list)
- {
- this.innerlist = list; this.underlying = underlying; this.slidableView = slidableView;
- }
- #endregion
- #region IList<T> Members
- /// <summary>
- ///
- /// </summary>
- /// <value>The first item of the wrapped list</value>
- public T First { get { return innerlist.First; } }
- /// <summary>
- ///
- /// </summary>
- /// <value>The last item of the wrapped list</value>
- public T Last { get { return innerlist.Last; } }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> if used as setter</exception>
- /// <value>True if wrapped list has FIFO semantics for the Add(T item) and Remove() methods</value>
- public bool FIFO
- {
- get { return innerlist.FIFO; }
- set { throw new ReadOnlyCollectionException("List is read only"); }
- }
- /// <summary>
- ///
- /// </summary>
- public virtual bool IsFixedSize
- {
- get { return true; }
- }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> if used as setter</exception>
- /// <value>The i'th item of the wrapped list</value>
- public T this[int i]
- {
- get { return innerlist[i]; }
- set { throw new ReadOnlyCollectionException("List is read only"); }
- }
- /// <summary>
- ///
- /// </summary>
- /// <value></value>
- public virtual Speed IndexingSpeed { get { return innerlist.IndexingSpeed; } }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="index"></param>
- /// <param name="item"></param>
- public void Insert(int index, T item)
- { throw new ReadOnlyCollectionException(); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="pointer"></param>
- /// <param name="item"></param>
- public void Insert(IList<T> pointer, T item)
- { throw new ReadOnlyCollectionException(); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- public void InsertFirst(T item)
- { throw new ReadOnlyCollectionException("List is read only"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- public void InsertLast(T item)
- { throw new ReadOnlyCollectionException("List is read only"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <param name="target"></param>
- public void InsertBefore(T item, T target)
- { throw new ReadOnlyCollectionException("List is read only"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="item"></param>
- /// <param name="target"></param>
- public void InsertAfter(T item, T target)
- { throw new ReadOnlyCollectionException("List is read only"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <param name="i"></param>
- /// <param name="items"></param>
- public void InsertAll<U>(int i, SCG.IEnumerable<U> items) where U : T
- { throw new ReadOnlyCollectionException("List is read only"); }
- /// <summary>
- /// Perform FindAll on the wrapped list. The result is <b>not</b> necessarily read-only.
- /// </summary>
- /// <param name="filter">The filter to use</param>
- /// <returns></returns>
- public IList<T> FindAll(Fun<T, bool> filter) { return innerlist.FindAll(filter); }
- /// <summary>
- /// Perform Map on the wrapped list. The result is <b>not</b> necessarily read-only.
- /// </summary>
- /// <typeparam name="V">The type of items of the new list</typeparam>
- /// <param name="mapper">The mapper to use.</param>
- /// <returns>The mapped list</returns>
- public IList<V> Map<V>(Fun<T, V> mapper) { return innerlist.Map(mapper); }
- /// <summary>
- /// Perform Map on the wrapped list. The result is <b>not</b> necessarily read-only.
- /// </summary>
- /// <typeparam name="V">The type of items of the new list</typeparam>
- /// <param name="mapper">The delegate defining the map.</param>
- /// <param name="itemequalityComparer">The itemequalityComparer to use for the new list</param>
- /// <returns>The new list.</returns>
- public IList<V> Map<V>(Fun<T, V> mapper, SCG.IEqualityComparer<V> itemequalityComparer) { return innerlist.Map(mapper, itemequalityComparer); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <returns></returns>
- public T Remove() { throw new ReadOnlyCollectionException("List is read only"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <returns></returns>
- public T RemoveFirst() { throw new ReadOnlyCollectionException("List is read only"); }
- /// <summary>
- /// </summary>
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>
- /// <returns></returns>
- public T RemoveLast() { throw new ReadOnlyCollectionException("List is read only"); }
- /// <summary>
- /// Create the indicated view on the wrapped list and wrap it read-only.
- /// </summary>
- /// <param name="start"></param>
- /// <param name="count"></param>
- /// <returns></returns>
- public IList<T> View(int start, int count)
- {
- IList<T> view =…
Large files files are truncated, but you can click here to view the full file