Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id EC2AE200BBB for ; Thu, 10 Nov 2016 12:47:19 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id EA9CB160B24; Thu, 10 Nov 2016 11:47:19 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id D9AC7160B01 for ; Thu, 10 Nov 2016 12:47:16 +0100 (CET) Received: (qmail 30117 invoked by uid 500); 10 Nov 2016 11:47:15 -0000 Mailing-List: contact commits-help@lucenenet.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: lucene-net-dev@lucenenet.apache.org Delivered-To: mailing list commits@lucenenet.apache.org Received: (qmail 29968 invoked by uid 99); 10 Nov 2016 11:47:15 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 10 Nov 2016 11:47:15 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 1ACB9E3AA8; Thu, 10 Nov 2016 11:47:15 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: nightowl888@apache.org To: commits@lucenenet.apache.org Date: Thu, 10 Nov 2016 11:47:17 -0000 Message-Id: <9d3b15b0f1184936927e582496d2258c@git.apache.org> In-Reply-To: <75d0a803894f49d5a0c77d723f975556@git.apache.org> References: <75d0a803894f49d5a0c77d723f975556@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [03/58] [abbrv] lucenenet git commit: Added TreeSet and TreeDictionary from C5 to the Support namespace archived-at: Thu, 10 Nov 2016 11:47:20 -0000 http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5f198526/src/Lucene.Net.Tests/core/Support/C5/Wrappers.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Tests/core/Support/C5/Wrappers.cs b/src/Lucene.Net.Tests/core/Support/C5/Wrappers.cs new file mode 100644 index 0000000..73ed656 --- /dev/null +++ b/src/Lucene.Net.Tests/core/Support/C5/Wrappers.cs @@ -0,0 +1,2338 @@ +/* + Copyright (c) 2003-2016 Niels Kokholm, Peter Sestoft, and Rasmus Lystrøm + 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.Collections.Generic; + +namespace Lucene.Net.Support.C5 +{ + /// + /// A read-only wrapper class for a generic enumerator + /// + [Serializable] + public class GuardedEnumerator : IEnumerator + { + #region Fields + + IEnumerator enumerator; + + #endregion + + #region Constructor + + /// + /// Create a wrapper around a generic enumerator + /// + /// The enumerator to wrap + public GuardedEnumerator(IEnumerator enumerator) + { this.enumerator = enumerator; } + + #endregion + + #region IEnumerator Members + + /// + /// Move wrapped enumerator to next item, or the first item if + /// this is the first call to MoveNext. + /// + /// True if enumerator is valid now + public bool MoveNext() { return enumerator.MoveNext(); } + + + /// + /// Undefined if enumerator is not valid (MoveNext hash been called returning true) + /// + /// The current item of the wrapped enumerator. + public T Current { get { return enumerator.Current; } } + + #endregion + + #region IDisposable Members + + //TODO: consider possible danger of calling through to Dispose. + /// + /// Dispose wrapped enumerator. + /// + 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 + } + + + + /// + /// A read-only wrapper class for a generic enumerable + /// + /// This is mainly interesting as a base of other guard classes + /// + [Serializable] + public class GuardedEnumerable : System.Collections.Generic.IEnumerable + { + #region Fields + + System.Collections.Generic.IEnumerable enumerable; + + #endregion + + #region Constructor + + /// + /// Wrap an enumerable in a read-only wrapper + /// + /// The enumerable to wrap + public GuardedEnumerable(System.Collections.Generic.IEnumerable enumerable) + { this.enumerable = enumerable; } + + #endregion + + #region System.Collections.Generic.IEnumerable Members + + /// + /// Get an enumerator from the wrapped enumerable + /// + /// The enumerator (itself wrapped) + public IEnumerator GetEnumerator() + { return new GuardedEnumerator(enumerable.GetEnumerator()); } + + #endregion + + #region IEnumerable Members + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #endregion + + } + + + + /// + /// A read-only wrapper for a generic directed enumerable + /// + /// This is mainly interesting as a base of other guard classes + /// + [Serializable] + public class GuardedDirectedEnumerable : GuardedEnumerable, IDirectedEnumerable + { + #region Fields + + IDirectedEnumerable directedenumerable; + + #endregion + + #region Constructor + + /// + /// Wrap a directed enumerable in a read-only wrapper + /// + /// the collection to wrap + public GuardedDirectedEnumerable(IDirectedEnumerable directedenumerable) + : base(directedenumerable) + { this.directedenumerable = directedenumerable; } + + #endregion + + #region IDirectedEnumerable Members + + /// + /// Get a enumerable that enumerates the wrapped collection in the opposite direction + /// + /// The mirrored enumerable + public IDirectedEnumerable Backwards() + { return new GuardedDirectedEnumerable(directedenumerable.Backwards()); } + + + /// + /// Forwards if same, else Backwards + /// + /// The enumeration direction relative to the original collection. + public EnumerationDirection Direction + { get { return directedenumerable.Direction; } } + + #endregion + } + + + + /// + /// A read-only wrapper for an ICollectionValue<T> + /// + /// This is mainly interesting as a base of other guard classes + /// + [Serializable] + public class GuardedCollectionValue : GuardedEnumerable, ICollectionValue + { + #region Events + /// + /// The ListenableEvents value of the wrapped collection + /// + /// + public virtual EventTypeEnum ListenableEvents { get { return collectionvalue.ListenableEvents; } } + + /// + /// The ActiveEvents value of the wrapped collection + /// + /// + public virtual EventTypeEnum ActiveEvents { get { return collectionvalue.ActiveEvents; } } + + ProxyEventBlock eventBlock; + /// + /// The change event. Will be raised for every change operation on the collection. + /// + public event CollectionChangedHandler CollectionChanged + { + add { (eventBlock ?? (eventBlock = new ProxyEventBlock(this, collectionvalue))).CollectionChanged += value; } + remove { if (eventBlock != null) eventBlock.CollectionChanged -= value; } + } + + /// + /// The change event. Will be raised for every change operation on the collection. + /// + public event CollectionClearedHandler CollectionCleared + { + add { (eventBlock ?? (eventBlock = new ProxyEventBlock(this, collectionvalue))).CollectionCleared += value; } + remove { if (eventBlock != null) eventBlock.CollectionCleared -= value; } + } + + /// + /// The item added event. Will be raised for every individual addition to the collection. + /// + public event ItemsAddedHandler ItemsAdded + { + add { (eventBlock ?? (eventBlock = new ProxyEventBlock(this, collectionvalue))).ItemsAdded += value; } + remove { if (eventBlock != null) eventBlock.ItemsAdded -= value; } + } + + /// + /// The item added event. Will be raised for every individual addition to the collection. + /// + public event ItemInsertedHandler ItemInserted + { + add { (eventBlock ?? (eventBlock = new ProxyEventBlock(this, collectionvalue))).ItemInserted += value; } + remove { if (eventBlock != null) eventBlock.ItemInserted -= value; } + } + + /// + /// The item removed event. Will be raised for every individual removal from the collection. + /// + public event ItemsRemovedHandler ItemsRemoved + { + add { (eventBlock ?? (eventBlock = new ProxyEventBlock(this, collectionvalue))).ItemsRemoved += value; } + remove { if (eventBlock != null) eventBlock.ItemsRemoved -= value; } + } + + /// + /// The item removed event. Will be raised for every individual removal from the collection. + /// + public event ItemRemovedAtHandler ItemRemovedAt + { + add { (eventBlock ?? (eventBlock = new ProxyEventBlock(this, collectionvalue))).ItemRemovedAt += value; } + remove { if (eventBlock != null) eventBlock.ItemRemovedAt -= value; } + } + #endregion + + #region Fields + + ICollectionValue collectionvalue; + + #endregion + + #region Constructor + + /// + /// Wrap a ICollectionValue<T> in a read-only wrapper + /// + /// the collection to wrap + public GuardedCollectionValue(ICollectionValue collectionvalue) + : base(collectionvalue) + { this.collectionvalue = collectionvalue; } + + #endregion + + #region ICollection Members + + /// + /// Get the size of the wrapped collection + /// + /// The size + public virtual bool IsEmpty { get { return collectionvalue.IsEmpty; } } + + /// + /// Get the size of the wrapped collection + /// + /// The size + public virtual int Count { get { return collectionvalue.Count; } } + + /// + /// The value is symbolic indicating the type of asymptotic complexity + /// in terms of the size of this collection (worst-case or amortized as + /// relevant). + /// + /// A characterization of the speed of the + /// Count property in this collection. + public virtual Speed CountSpeed { get { return collectionvalue.CountSpeed; } } + + /// + /// Copy the items of the wrapped collection to an array + /// + /// The array + /// Starting offset + public virtual void CopyTo(T[] a, int i) { collectionvalue.CopyTo(a, i); } + + /// + /// Create an array from the items of the wrapped collection + /// + /// The array + public virtual T[] ToArray() { return collectionvalue.ToArray(); } + + /// + /// Apply a delegate to all items of the wrapped enumerable. + /// + /// The delegate to apply + //TODO: change this to throw an exception? + public virtual void Apply(Action a) { collectionvalue.Apply(a); } + + + /// + /// Check if there exists an item that satisfies a + /// specific predicate in the wrapped enumerable. + /// + /// A filter delegate + /// () defining the predicate + /// True is such an item exists + public virtual bool Exists(Func filter) { return collectionvalue.Exists(filter); } + + /// + /// + /// + /// + /// + /// + public virtual bool Find(Func filter, out T item) { return collectionvalue.Find(filter, out item); } + + /// + /// Check if all items in the wrapped enumerable satisfies a specific predicate. + /// + /// A filter delegate + /// () defining the predicate + /// True if all items satisfies the predicate + public virtual bool All(Func filter) { return collectionvalue.All(filter); } + + /// + /// Create an enumerable, enumerating the items of this collection that satisfies + /// a certain condition. + /// + /// The T->bool filter delegate defining the condition + /// The filtered enumerable + public virtual System.Collections.Generic.IEnumerable Filter(Func filter) { return collectionvalue.Filter(filter); } + + /// + /// Choose some item of this collection. + /// + /// if collection is empty. + /// + public virtual T Choose() { return collectionvalue.Choose(); } + + #endregion + + #region IShowable Members + + /// + /// + /// + /// + /// + /// + /// + public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider) + { + return collectionvalue.Show(stringbuilder, ref rest, formatProvider); + } + #endregion + + #region IFormattable Members + + /// + /// + /// + /// + /// + /// + public string ToString(string format, IFormatProvider formatProvider) + { + return collectionvalue.ToString(format, formatProvider); + } + + #endregion + } + + + + /// + /// A read-only wrapper for a directed collection + /// + /// This is mainly interesting as a base of other guard classes + /// + [Serializable] + public class GuardedDirectedCollectionValue : GuardedCollectionValue, IDirectedCollectionValue + { + #region Fields + + IDirectedCollectionValue directedcollection; + + #endregion + + #region Constructor + + /// + /// Wrap a directed collection in a read-only wrapper + /// + /// the collection to wrap + public GuardedDirectedCollectionValue(IDirectedCollectionValue directedcollection) + : + base(directedcollection) + { this.directedcollection = directedcollection; } + + #endregion + + #region IDirectedCollection Members + + /// + /// Get a collection that enumerates the wrapped collection in the opposite direction + /// + /// The mirrored collection + public virtual IDirectedCollectionValue Backwards() + { return new GuardedDirectedCollectionValue(directedcollection.Backwards()); } + + /// + /// + /// + /// + /// + /// + public virtual bool FindLast(Func predicate, out T item) { return directedcollection.FindLast(predicate, out item); } + + #endregion + + #region IDirectedEnumerable Members + + IDirectedEnumerable IDirectedEnumerable.Backwards() + { return Backwards(); } + + + /// + /// Forwards if same, else Backwards + /// + /// The enumeration direction relative to the original collection. + public EnumerationDirection Direction + { get { return directedcollection.Direction; } } + + #endregion + } + + + + /// + /// A read-only wrapper for an , + /// + /// Suitable for wrapping hash tables, + /// and + /// + [Serializable] + public class GuardedCollection : GuardedCollectionValue, ICollection + { + #region Fields + + ICollection collection; + + #endregion + + #region Constructor + + /// + /// Wrap an ICollection<T> in a read-only wrapper + /// + /// the collection to wrap + public GuardedCollection(ICollection collection) + : base(collection) + { + this.collection = collection; + } + + #endregion + + #region ICollection Members + + /// + /// (This is a read-only wrapper) + /// + /// True + public virtual bool IsReadOnly { get { return true; } } + + + /// + /// Speed of wrapped collection + public virtual Speed ContainsSpeed { get { return collection.ContainsSpeed; } } + + /// + /// + /// + /// + public virtual int GetUnsequencedHashCode() + { return collection.GetUnsequencedHashCode(); } + + /// + /// + /// + /// + /// + public virtual bool UnsequencedEquals(ICollection that) + { return collection.UnsequencedEquals(that); } + + + /// + /// Check if an item is in the wrapped collection + /// + /// The item + /// True if found + public virtual bool Contains(T item) { return collection.Contains(item); } + + + /// + /// Count the number of times an item appears in the wrapped collection + /// + /// The item + /// The number of copies + public virtual int ContainsCount(T item) { return collection.ContainsCount(item); } + + /// + /// + /// + /// + public virtual ICollectionValue UniqueItems() { return new GuardedCollectionValue(collection.UniqueItems()); } + + /// + /// + /// + /// + public virtual ICollectionValue> ItemMultiplicities() { return new GuardedCollectionValue>(collection.ItemMultiplicities()); } + + /// + /// Check if all items in the argument is in the wrapped collection + /// + /// The items + /// True if so + public virtual bool ContainsAll(System.Collections.Generic.IEnumerable items) { return collection.ContainsAll(items); } + + /// + /// Search for an item in the wrapped collection + /// + /// On entry the item to look for, on exit the equivalent item found (if any) + /// + public virtual bool Find(ref T item) { return collection.Find(ref item); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public virtual bool FindOrAdd(ref T item) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public virtual bool Update(T item) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + public virtual bool Update(T item, out T olditem) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public virtual bool UpdateOrAdd(T item) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + public virtual bool UpdateOrAdd(T item, out T olditem) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + /// + /// + /// since this is a read-only wrapper + /// + /// + public virtual bool Remove(T item) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// The value to remove. + /// The removed value. + /// + public virtual bool Remove(T item, out T removeditem) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + public virtual void RemoveAllCopies(T item) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + public virtual void RemoveAll(System.Collections.Generic.IEnumerable items) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + /// + /// + /// since this is a read-only wrapper + public virtual void Clear() + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + public virtual void RetainAll(System.Collections.Generic.IEnumerable items) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + /// + /// Check wrapped collection for internal consistency + /// + /// True if check passed + public virtual bool Check() { return collection.Check(); } + + #endregion + + #region IExtensible Members + + /// + /// False if wrapped collection has set semantics + public virtual bool AllowsDuplicates { get { return collection.AllowsDuplicates; } } + + //TODO: the equalityComparer should be guarded + /// + /// + /// + /// + public virtual System.Collections.Generic.IEqualityComparer EqualityComparer { get { return collection.EqualityComparer; } } + + /// + /// By convention this is true for any collection with set semantics. + /// + /// True if only one representative of a group of equal items + /// is kept in the collection together with the total count. + public virtual bool DuplicatesByCounting { get { return collection.DuplicatesByCounting; } } + + + /// + /// True if wrapped collection is empty + public override bool IsEmpty { get { return collection.IsEmpty; } } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public virtual bool Add(T item) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// since this is a read-only wrapper + /// + void System.Collections.Generic.ICollection.Add(T item) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// since this is a read-only wrapper + /// + public virtual void AddAll(System.Collections.Generic.IEnumerable items) + { throw new ReadOnlyCollectionException(); } + + #endregion + } + + + /// + /// A read-only wrapper for a sequenced collection + /// + /// This is mainly interesting as a base of other guard classes + /// + [Serializable] + public class GuardedSequenced : GuardedCollection, ISequenced + { + #region Fields + + ISequenced sequenced; + + #endregion + + #region Constructor + + /// + /// Wrap a sequenced collection in a read-only wrapper + /// + /// + public GuardedSequenced(ISequenced sorted) : base(sorted) { this.sequenced = sorted; } + + #endregion + + /// + /// Check if there exists an item that satisfies a + /// specific predicate in this collection and return the index of the first one. + /// + /// A delegate + /// ( with R == bool) defining the predicate + /// the index, if found, a negative value else + public int FindIndex(Func predicate) + { + IIndexed indexed = sequenced as IIndexed; + if (indexed != null) + return indexed.FindIndex(predicate); + int index = 0; + foreach (T item in this) + { + if (predicate(item)) + return index; + index++; + } + return -1; + } + + /// + /// Check if there exists an item that satisfies a + /// specific predicate in this collection and return the index of the last one. + /// + /// A delegate + /// ( with R == bool) defining the predicate + /// the index, if found, a negative value else + public int FindLastIndex(Func predicate) + { + IIndexed indexed = sequenced as IIndexed; + 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 Members + + /// + /// + /// + /// + public int GetSequencedHashCode() + { return sequenced.GetSequencedHashCode(); } + + /// + /// + /// + /// + /// + public bool SequencedEquals(ISequenced that) + { return sequenced.SequencedEquals(that); } + + #endregion + + #region IDirectedCollection Members + + /// + /// Get a collection that enumerates the wrapped collection in the opposite direction + /// + /// The mirrored collection + public virtual IDirectedCollectionValue Backwards() + { return new GuardedDirectedCollectionValue(sequenced.Backwards()); } + + /// + /// + /// + /// + /// + /// + public virtual bool FindLast(Func predicate, out T item) { return sequenced.FindLast(predicate, out item); } + + #endregion + + #region IDirectedEnumerable Members + + IDirectedEnumerable IDirectedEnumerable.Backwards() + { return Backwards(); } + + + + /// + /// Forwards if same, else Backwards + /// + /// The enumeration direction relative to the original collection. + public EnumerationDirection Direction + { get { return EnumerationDirection.Forwards; } } + + #endregion + } + + + /// + /// A read-only wrapper for a sorted collection + /// + /// This is mainly interesting as a base of other guard classes + /// + [Serializable] + public class GuardedSorted : GuardedSequenced, ISorted + { + #region Fields + + ISorted sorted; + + #endregion + + #region Constructor + + /// + /// Wrap a sorted collection in a read-only wrapper + /// + /// + public GuardedSorted(ISorted sorted) : base(sorted) { this.sorted = sorted; } + + #endregion + + #region ISorted Members + + /// + /// Find the strict predecessor of item in the guarded sorted collection, + /// that is, the greatest item in the collection smaller than the item. + /// + /// The item to find the predecessor for. + /// The predecessor, if any; otherwise the default value for T. + /// True if item has a predecessor; otherwise false. + public bool TryPredecessor(T item, out T res) { return sorted.TryPredecessor(item, out res); } + + + /// + /// Find the strict successor of item in the guarded sorted collection, + /// that is, the least item in the collection greater than the supplied value. + /// + /// The item to find the successor for. + /// The successor, if any; otherwise the default value for T. + /// True if item has a successor; otherwise false. + public bool TrySuccessor(T item, out T res) { return sorted.TrySuccessor(item, out res); } + + + /// + /// 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. + /// + /// The item to find the weak predecessor for. + /// The weak predecessor, if any; otherwise the default value for T. + /// True if item has a weak predecessor; otherwise false. + public bool TryWeakPredecessor(T item, out T res) { return sorted.TryWeakPredecessor(item, out res); } + + + /// + /// 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. + /// + /// The item to find the weak successor for. + /// The weak successor, if any; otherwise the default value for T. + /// True if item has a weak successor; otherwise false. + public bool TryWeakSuccessor(T item, out T res) { return sorted.TryWeakSuccessor(item, out res); } + + + /// + /// Find the predecessor of the item in the wrapped sorted collection + /// + /// if no such element exists + /// The item + /// The predecessor + public T Predecessor(T item) { return sorted.Predecessor(item); } + + + /// + /// Find the Successor of the item in the wrapped sorted collection + /// + /// if no such element exists + /// The item + /// The Successor + public T Successor(T item) { return sorted.Successor(item); } + + + /// + /// Find the weak predecessor of the item in the wrapped sorted collection + /// + /// if no such element exists + /// The item + /// The weak predecessor + public T WeakPredecessor(T item) { return sorted.WeakPredecessor(item); } + + + /// + /// Find the weak Successor of the item in the wrapped sorted collection + /// + /// if no such element exists + /// The item + /// The weak Successor + public T WeakSuccessor(T item) { return sorted.WeakSuccessor(item); } + + + /// + /// Run Cut on the wrapped sorted collection + /// + /// + /// + /// + /// + /// + /// + public bool Cut(IComparable 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); } + + + /// + /// Get the specified range from the wrapped collection. + /// (The current implementation erroneously does not wrap the result.) + /// + /// + /// + public IDirectedEnumerable RangeFrom(T bot) { return sorted.RangeFrom(bot); } + + + /// + /// Get the specified range from the wrapped collection. + /// (The current implementation erroneously does not wrap the result.) + /// + /// + /// + /// + public IDirectedEnumerable RangeFromTo(T bot, T top) + { return sorted.RangeFromTo(bot, top); } + + + /// + /// Get the specified range from the wrapped collection. + /// (The current implementation erroneously does not wrap the result.) + /// + /// + /// + public IDirectedEnumerable RangeTo(T top) { return sorted.RangeTo(top); } + + + /// + /// Get the specified range from the wrapped collection. + /// (The current implementation erroneously does not wrap the result.) + /// + /// + public IDirectedCollectionValue RangeAll() { return sorted.RangeAll(); } + + /// + /// + /// since this is a read-only wrapper + /// + public void AddSorted(System.Collections.Generic.IEnumerable items) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + /// + /// + /// since this is a read-only wrapper + /// + public void RemoveRangeFrom(T low) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void RemoveRangeFromTo(T low, T hi) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + public void RemoveRangeTo(T hi) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + #endregion + + #region IPriorityQueue Members + + /// + /// Find the minimum of the wrapped collection + /// + /// The minimum + public T FindMin() { return sorted.FindMin(); } + + + /// + /// + /// since this is a read-only wrapper + /// + public T DeleteMin() + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// Find the maximum of the wrapped collection + /// + /// The maximum + public T FindMax() { return sorted.FindMax(); } + + + /// + /// + /// since this is a read-only wrapper + /// + public T DeleteMax() + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + //TODO: we should guard the comparer! + /// + /// The comparer object supplied at creation time for the underlying collection + /// + /// The comparer + public System.Collections.Generic.IComparer Comparer { get { return sorted.Comparer; } } + #endregion + + #region IDirectedEnumerable Members + + IDirectedEnumerable IDirectedEnumerable.Backwards() + { return Backwards(); } + + #endregion + } + + + + /// + /// Read-only wrapper for indexed sorted collections + /// + /// Suitable for wrapping TreeSet, TreeBag and SortedArray + /// + [Serializable] + public class GuardedIndexedSorted : GuardedSorted, IIndexedSorted + { + #region Fields + + IIndexedSorted indexedsorted; + + #endregion + + #region Constructor + + /// + /// Wrap an indexed sorted collection in a read-only wrapper + /// + /// the indexed sorted collection + public GuardedIndexedSorted(IIndexedSorted list) + : base(list) + { this.indexedsorted = list; } + + #endregion + + #region IIndexedSorted Members + + /// + /// Get the specified range from the wrapped collection. + /// (The current implementation erroneously does not wrap the result.) + /// + /// + /// + public new IDirectedCollectionValue RangeFrom(T bot) + { return indexedsorted.RangeFrom(bot); } + + + /// + /// Get the specified range from the wrapped collection. + /// (The current implementation erroneously does not wrap the result.) + /// + /// + /// + /// + public new IDirectedCollectionValue RangeFromTo(T bot, T top) + { return indexedsorted.RangeFromTo(bot, top); } + + + /// + /// Get the specified range from the wrapped collection. + /// (The current implementation erroneously does not wrap the result.) + /// + /// + /// + public new IDirectedCollectionValue RangeTo(T top) + { return indexedsorted.RangeTo(top); } + + + /// + /// Report the number of items in the specified range of the wrapped collection + /// + /// + /// + public int CountFrom(T bot) { return indexedsorted.CountFrom(bot); } + + + /// + /// Report the number of items in the specified range of the wrapped collection + /// + /// + /// + /// + public int CountFromTo(T bot, T top) { return indexedsorted.CountFromTo(bot, top); } + + + /// + /// Report the number of items in the specified range of the wrapped collection + /// + /// + /// + public int CountTo(T top) { return indexedsorted.CountTo(top); } + + + /// + /// Run FindAll on the wrapped collection with the indicated filter. + /// The result will not be read-only. + /// + /// + /// + public IIndexedSorted FindAll(Func f) + { return indexedsorted.FindAll(f); } + + + /// + /// Run Map on the wrapped collection with the indicated mapper. + /// The result will not be read-only. + /// + /// + /// The comparer to use in the result + /// + public IIndexedSorted Map(Func m, System.Collections.Generic.IComparer c) + { return indexedsorted.Map(m, c); } + + #endregion + + #region IIndexed Members + + /// + /// + /// + /// The i'th item of the wrapped sorted collection + public T this[int i] { get { return indexedsorted[i]; } } + + /// + /// + /// + /// + public virtual Speed IndexingSpeed { get { return indexedsorted.IndexingSpeed; } } + + /// + /// A directed collection of the items in the indicated interval of the wrapped collection + public IDirectedCollectionValue this[int start, int end] + { get { return new GuardedDirectedCollectionValue(indexedsorted[start, end]); } } + + + /// + /// Find the (first) index of an item in the wrapped collection + /// + /// + /// + public int IndexOf(T item) { return indexedsorted.IndexOf(item); } + + + /// + /// Find the last index of an item in the wrapped collection + /// + /// + /// + public int LastIndexOf(T item) { return indexedsorted.LastIndexOf(item); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public T RemoveAt(int i) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void RemoveInterval(int start, int count) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + #endregion + + #region IDirectedEnumerable Members + + IDirectedEnumerable IDirectedEnumerable.Backwards() + { return Backwards(); } + + #endregion + } + + + + /// + /// A read-only wrapper for a generic list collection + /// Suitable as a wrapper for LinkedList, HashedLinkedList, ArrayList and HashedArray. + /// , + /// , + /// or + /// . + /// + /// + [Serializable] + public class GuardedList : GuardedSequenced, IList, System.Collections.Generic.IList + { + #region Fields + + IList innerlist; + GuardedList underlying; + bool slidableView = false; + + #endregion + + #region Constructor + + /// + /// 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. + /// + /// The list + public GuardedList(IList 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(list.Underlying, null, false); + } + + GuardedList(IList list, GuardedList underlying, bool slidableView) + : base(list) + { + this.innerlist = list; this.underlying = underlying; this.slidableView = slidableView; + } + #endregion + + #region IList Members + + /// + /// + /// + /// The first item of the wrapped list + public T First { get { return innerlist.First; } } + + + /// + /// + /// + /// The last item of the wrapped list + public T Last { get { return innerlist.Last; } } + + + /// + /// + /// if used as setter + /// True if wrapped list has FIFO semantics for the Add(T item) and Remove() methods + public bool FIFO + { + get { return innerlist.FIFO; } + set { throw new ReadOnlyCollectionException("List is read only"); } + } + + /// + /// + /// + public virtual bool IsFixedSize + { + get { return true; } + } + + + /// + /// + /// if used as setter + /// The i'th item of the wrapped list + public T this[int i] + { + get { return innerlist[i]; } + set { throw new ReadOnlyCollectionException("List is read only"); } + } + + /// + /// + /// + /// + public virtual Speed IndexingSpeed { get { return innerlist.IndexingSpeed; } } + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void Insert(int index, T item) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void Insert(IList pointer, T item) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// since this is a read-only wrapper + /// + public void InsertFirst(T item) + { throw new ReadOnlyCollectionException("List is read only"); } + + /// + /// + /// since this is a read-only wrapper + /// + public void InsertLast(T item) + { throw new ReadOnlyCollectionException("List is read only"); } + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void InsertBefore(T item, T target) + { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void InsertAfter(T item, T target) + { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void InsertAll(int i, System.Collections.Generic.IEnumerable items) + { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// Perform FindAll on the wrapped list. The result is not necessarily read-only. + /// + /// The filter to use + /// + public IList FindAll(Func filter) { return innerlist.FindAll(filter); } + + + /// + /// Perform Map on the wrapped list. The result is not necessarily read-only. + /// + /// The type of items of the new list + /// The mapper to use. + /// The mapped list + public IList Map(Func mapper) { return innerlist.Map(mapper); } + + /// + /// Perform Map on the wrapped list. The result is not necessarily read-only. + /// + /// The type of items of the new list + /// The delegate defining the map. + /// The itemequalityComparer to use for the new list + /// The new list. + public IList Map(Func mapper, System.Collections.Generic.IEqualityComparer itemequalityComparer) { return innerlist.Map(mapper, itemequalityComparer); } + + /// + /// + /// since this is a read-only wrapper + /// + public T Remove() { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// + /// since this is a read-only wrapper + /// + public T RemoveFirst() { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// + /// since this is a read-only wrapper + /// + public T RemoveLast() { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// Create the indicated view on the wrapped list and wrap it read-only. + /// + /// + /// + /// + public IList View(int start, int count) + { + IList view = innerlist.View(start, count); + return view == null ? null : new GuardedList(view, underlying ?? this, true); + } + + /// + /// Create the indicated view on the wrapped list and wrap it read-only. + /// + /// + /// + public IList ViewOf(T item) + { + IList view = innerlist.ViewOf(item); + return view == null ? null : new GuardedList(view, underlying ?? this, true); + } + + /// + /// Create the indicated view on the wrapped list and wrap it read-only. + /// + /// + /// + public IList LastViewOf(T item) + { + IList view = innerlist.LastViewOf(item); + return view == null ? null : new GuardedList(view, underlying ?? this, true); + } + + + /// + /// + /// The wrapped underlying list of the wrapped view + public IList Underlying { get { return underlying; } } + + + /// + /// + /// + /// The offset of the wrapped list as a view. + public int Offset { get { return innerlist.Offset; } } + + /// + /// + /// + /// + public virtual bool IsValid { get { return innerlist.IsValid; } } + + /// + /// + /// if this is a wrapped view and not a view that was made on a wrapper + /// + public IList Slide(int offset) + { + if (slidableView) + { + innerlist.Slide(offset); + return this; + } + else + throw new ReadOnlyCollectionException("List is read only"); + } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public IList Slide(int offset, int size) + { + if (slidableView) + { + innerlist.Slide(offset, size); + return this; + } + else + throw new ReadOnlyCollectionException("List is read only"); + } + + + /// + /// + /// + /// since this is a read-only wrapper + /// + /// + public bool TrySlide(int offset) + { + if (slidableView) + return innerlist.TrySlide(offset); + else + throw new ReadOnlyCollectionException("List is read only"); + } + + /// + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + public bool TrySlide(int offset, int size) + { + if (slidableView) + return innerlist.TrySlide(offset, size); + else + throw new ReadOnlyCollectionException("List is read only"); + } + + /// + /// + /// + /// + /// + public IList Span(IList otherView) + { + GuardedList otherGuardedList = otherView as GuardedList; + if (otherGuardedList == null) + throw new IncompatibleViewException(); + IList span = innerlist.Span(otherGuardedList.innerlist); + if (span == null) + return null; + return new GuardedList(span, underlying ?? otherGuardedList.underlying ?? this, true); + } + + /// + /// since this is a read-only wrapper + /// + public void Reverse() { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void Reverse(int start, int count) + { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// Check if wrapped list is sorted according to the default sorting order + /// for the item type T, as defined by the class + /// + /// if T is not comparable + /// True if the list is sorted, else false. + public bool IsSorted() { return innerlist.IsSorted(System.Collections.Generic.Comparer.Default); } + + /// + /// Check if wrapped list is sorted + /// + /// The sorting order to use + /// True if sorted + public bool IsSorted(System.Collections.Generic.IComparer c) { return innerlist.IsSorted(c); } + + + /// + /// + /// since this is a read-only wrapper + public void Sort() + { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// + /// since this is a read-only wrapper + /// + public void Sort(System.Collections.Generic.IComparer c) + { throw new ReadOnlyCollectionException("List is read only"); } + + /// + /// + /// since this is a read-only wrapper + public void Shuffle() + { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// + /// since this is a read-only wrapper + /// + public void Shuffle(Random rnd) + { throw new ReadOnlyCollectionException("List is read only"); } + + #endregion + + #region IIndexed Members + + /// + /// A directed collection of the items in the indicated interval of the wrapped collection + public IDirectedCollectionValue this[int start, int end] + { get { return new GuardedDirectedCollectionValue(innerlist[start, end]); } } + + + /// + /// Find the (first) index of an item in the wrapped collection + /// + /// + /// + public int IndexOf(T item) { return innerlist.IndexOf(item); } + + + /// + /// Find the last index of an item in the wrapped collection + /// + /// + /// + public int LastIndexOf(T item) { return innerlist.LastIndexOf(item); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public T RemoveAt(int i) + { throw new ReadOnlyCollectionException("List is read only"); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void RemoveInterval(int start, int count) + { throw new ReadOnlyCollectionException("List is read only"); } + + #endregion + + #region IDirectedEnumerable Members + + IDirectedEnumerable IDirectedEnumerable.Backwards() + { return Backwards(); } + + #endregion + + #region IStack Members + + + /// + /// + /// + /// since this is a read-only wrapper + /// - + public void Push(T item) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + /// + /// + /// + /// since this is a read-only wrapper + /// - + public T Pop() + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + #endregion + + #region IQueue Members + + /// + /// + /// + /// since this is a read-only wrapper + /// - + public void Enqueue(T item) + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + /// + /// + /// + /// since this is a read-only wrapper + /// - + public T Dequeue() + { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); } + + #endregion + + #region IDisposable Members + + /// + /// Ignore: this may be called by a foreach or using statement. + /// + public void Dispose() { } + + #endregion + + #region System.Collections.Generic.IList Members + + void System.Collections.Generic.IList.RemoveAt(int index) + { + throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); + } + + void System.Collections.Generic.ICollection.Add(T item) + { + throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); + } + + #endregion + + #region System.Collections.ICollection Members + + bool System.Collections.ICollection.IsSynchronized + { + get { return false; } + } + + [Obsolete] + Object System.Collections.ICollection.SyncRoot + { + get { return 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 + { + throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); + } + } + + int System.Collections.IList.Add(Object o) + { + throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); + } + + 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) + { + throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); + } + + void System.Collections.IList.Remove(Object o) + { + throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); + } + + void System.Collections.IList.RemoveAt(int index) + { + throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); + } + + #endregion + } + + /// + /// A read-only wrapper for a generic indexable queue (allows indexing). + /// + /// Suitable for wrapping a + /// + /// The item type. + [Serializable] + public class GuardedQueue : GuardedDirectedCollectionValue, IQueue + { + #region Fields + + IQueue queue; + + #endregion + + #region Constructor + + /// + /// Wrap a queue in a read-only wrapper + /// + /// The queue + public GuardedQueue(IQueue queue) : base(queue) { this.queue = queue; } + + #endregion + + #region IQueue Members + /// + /// + /// + /// + public bool AllowsDuplicates { get { return queue.AllowsDuplicates; } } + + /// + /// Index into the wrapped queue + /// + /// + /// + public T this[int i] { get { return queue[i]; } } + + /// + /// + /// + /// since this is a read-only wrapper + /// - + public void Enqueue(T item) + { throw new ReadOnlyCollectionException("Queue cannot be modified through this guard object"); } + + /// + /// + /// + /// since this is a read-only wrapper + /// - + public T Dequeue() + { throw new ReadOnlyCollectionException("Queue cannot be modified through this guard object"); } + + #endregion + } + + /// + /// A read-only wrapper for a dictionary. + /// + /// Suitable for wrapping a HashDictionary. + /// + [Serializable] + public class GuardedDictionary : GuardedCollectionValue>, IDictionary + { + #region Fields + + IDictionary dict; + + #endregion + + #region Constructor + + /// + /// Wrap a dictionary in a read-only wrapper + /// + /// the dictionary + public GuardedDictionary(IDictionary dict) : base(dict) { this.dict = dict; } + + #endregion + + #region IDictionary Members + + /// + /// + /// + /// + public System.Collections.Generic.IEqualityComparer EqualityComparer { get { return dict.EqualityComparer; } } + + /// + /// + /// since this is a + /// read-only wrapper if used as a setter + /// Get the value corresponding to a key in the wrapped dictionary + public V this[K key] + { + get { return dict[key]; } + set { throw new ReadOnlyCollectionException(); } + } + + /// + /// (This is a read-only wrapper) + /// + /// True + public bool IsReadOnly { get { return true; } } + + + //TODO: guard with a read-only wrapper? Probably so! + /// + /// The collection of keys of the wrapped dictionary + public ICollectionValue Keys + { get { return dict.Keys; } } + + + /// + /// The collection of values of the wrapped dictionary + public ICollectionValue Values { get { return dict.Values; } } + + /// + /// + /// + public virtual Func Func { get { return delegate (K k) { return this[k]; }; } } + + /// + /// + /// since this is a read-only wrapper + /// + /// + public void Add(K key, V val) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// + /// since this is a read-only wrapper + /// + public void AddAll(System.Collections.Generic.IEnumerable> items) + where L : K + where W : V + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// since this is a read-only wrapper + /// + /// + public bool Remove(K key) + { throw new ReadOnlyCollectionException(); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + public bool Remove(K key, out V val) + { throw new ReadOnlyCollectionException(); } + + + /// + /// + /// since this is a read-only wrapper + public void Clear() + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// + /// + public Speed ContainsSpeed { get { return dict.ContainsSpeed; } } + + /// + /// Check if the wrapped dictionary contains a specific key + /// + /// The key + /// True if it does + public bool Contains(K key) { return dict.Contains(key); } + + /// + /// + /// + /// + /// + public bool ContainsAll(System.Collections.Generic.IEnumerable keys) where H : K { return dict.ContainsAll(keys); } + + /// + /// Search for a key in the wrapped dictionary, reporting the value if found + /// + /// The key + /// On exit: the value if found + /// True if found + public bool Find(ref K key, out V val) { return dict.Find(ref key, out val); } + + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + public bool Update(K key, V val) + { throw new ReadOnlyCollectionException(); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + /// + public bool Update(K key, V val, out V oldval) + { throw new ReadOnlyCollectionException(); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + public bool FindOrAdd(K key, ref V val) + { throw new ReadOnlyCollectionException(); } + + + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + public bool UpdateOrAdd(K key, V val) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// since this is a read-only wrapper + /// + /// + /// + /// + public bool UpdateOrAdd(K key, V val, out V oldval) + { throw new ReadOnlyCollectionException(); } + + + /// + /// Check the internal consistency of the wrapped dictionary + /// + /// True if check passed + public bool Check() { return dict.Check(); } + + #endregion + } + + + + /// + /// A read-only wrapper for a sorted dictionary. + /// + /// Suitable for wrapping a Dictionary. + /// + [Serializable] + public class GuardedSortedDictionary : GuardedDictionary, ISortedDictionary + { + #region Fields + + ISortedDictionary sorteddict; + + #endregion + + #region Constructor + + /// + /// Wrap a sorted dictionary in a read-only wrapper + /// + /// the dictionary + public GuardedSortedDictionary(ISortedDictionary sorteddict) + : base(sorteddict) + { this.sorteddict = sorteddict; } + + #endregion + + #region ISortedDictionary Members + + /// + /// The key comparer used by this dictionary. + /// + /// + public System.Collections.Generic.IComparer Comparer { get { return sorteddict.Comparer; } } + + /// + /// + /// + /// + public new ISorted Keys { get { return null; } } + + /// + /// Find the entry in the dictionary whose key is the + /// predecessor of the specified key. + /// + /// The key + /// The predecessor, if any + /// True if key has a predecessor + public bool TryPredecessor(K key, out KeyValuePair res) + { + return sorteddict.TryPredecessor(key, out res); + } + + /// + /// Find the entry in the dictionary whose key is the + /// successor of the specified key. + /// + /// The key + /// The successor, if any + /// True if the key has a successor + public bool TrySuccessor(K key, out KeyValuePair res) + { + return sorteddict.TrySuccessor(key, out res); + } + + /// + /// Find the entry in the dictionary whose key is the + /// weak predecessor of the specified key. + /// + /// The key + /// The predecessor, if any + /// True if key has a weak predecessor + public bool TryWeakPredecessor(K key, out KeyValuePair res) + { + return sorteddict.TryWeakPredecessor(key, out res); + } + + /// + /// Find the entry in the dictionary whose key is the + /// weak successor of the specified key. + /// + /// The key + /// The weak successor, if any + /// True if the key has a weak successor + public bool TryWeakSuccessor(K key, out KeyValuePair res) + { + return sorteddict.TryWeakSuccessor(key, out res); + } + + /// + /// Get the entry in the wrapped dictionary whose key is the + /// predecessor of a specified key. + /// + /// if no such entry exists + /// The key + /// The entry + public KeyValuePair Predecessor(K key) + { return sorteddict.Predecessor(key); } + + /// + /// Get the entry in the wrapped dictionary whose key is the + /// successor of a specified key. + /// + /// if no such entry exists + /// The key + /// The entry + public KeyValuePair Successor(K key) + { return sorteddict.Successor(key); } + + + /// + /// Get the entry in the wrapped dictionary whose key is the + /// weak predecessor of a specified key. + /// + /// if no such entry exists + /// The key + /// The entry + public KeyValuePair WeakPredecessor(K key) + { return sorteddict.WeakPredecessor(key); } + + + /// + /// Get the entry in the wrapped dictionary whose key is the + /// weak successor of a specified key. + /// + /// if no such entry exists + /// The key + /// The entry + public KeyValuePair WeakSuccessor(K key) + { return sorteddict.WeakSuccessor(key); } + + /// + /// + /// + /// + public KeyValuePair FindMin() + { + return sorteddict.FindMin(); + } + + /// + /// + /// + /// since this is a read-only wrapper + /// + public KeyValuePair DeleteMin() + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// + /// + public KeyValuePair FindMax() + { + return sorteddict.FindMax(); + } + + /// + /// + /// + /// since this is a read-only wrapper + /// + public KeyValuePair DeleteMax() + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + public bool Cut(IComparable c, out KeyValuePair lowEntry, out bool lowIsValid, out KeyValuePair highEntry, out bool highIsValid) + { + return sorteddict.Cut(c, out lowEntry, out lowIsValid, out highEntry, out highIsValid); ; + } + + /// + /// + /// + /// + /// + public IDirectedEnumerable> RangeFrom(K bot) + { + return new GuardedDirectedEnumerable>(sorteddict.RangeFrom(bot)); + } + + /// + /// + /// + /// + /// + /// + public IDirectedEnumerable> RangeFromTo(K bot, K top) + { + return new GuardedDirectedEnumerable>(sorteddict.RangeFromTo(bot, top)); + } + + /// + /// + /// + /// + /// + public IDirectedEnumerable> RangeTo(K top) + { + return new GuardedDirectedEnumerable>(sorteddict.RangeTo(top)); + } + + /// + /// + /// + /// + public IDirectedCollectionValue> RangeAll() + { + return new GuardedDirectedCollectionValue>(sorteddict.RangeAll()); + } + + /// + /// + /// + /// since this is a read-only wrapper + /// + public void AddSorted(System.Collections.Generic.IEnumerable> items) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// + /// since this is a read-only wrapper + /// + public void RemoveRangeFrom(K low) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// + /// since this is a read-only wrapper + /// + /// + public void RemoveRangeFromTo(K low, K hi) + { throw new ReadOnlyCollectionException(); } + + /// + /// + /// + /// since this is a read-only wrapper + /// + public void RemoveRangeTo(K hi) + { throw new ReadOnlyCollectionException(); } + + #endregion + } + +} \ No newline at end of file