-// \r
-// System.Collections.SortedList.cs\r
-// \r
-// Author:\r
-// Sergey Chaban (serge@wildwestsoftware.com)\r
-// Duncan Mak (duncan@ximian.com)\r
-// Herve Poussineau (hpoussineau@fr.st\r
-// \r
-\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Globalization;\r
-\r
-namespace System.Collections {\r
-\r
- /// <summary>\r
- /// Represents a collection of associated keys and values\r
- /// that are sorted by the keys and are accessible by key\r
- /// and by index.\r
- /// </summary>\r
- [Serializable]\r
- public class SortedList : IDictionary, ICollection,\r
- IEnumerable, ICloneable {\r
-\r
-\r
- [Serializable]\r
- internal struct Slot {\r
- internal Object key;\r
- internal Object value;\r
- }\r
-\r
- private readonly static int INITIAL_SIZE = 16;\r
-\r
- private enum EnumeratorMode : int { KEY_MODE = 0, VALUE_MODE, ENTRY_MODE }\r
-\r
- private int inUse;\r
- private int modificationCount;\r
- private Slot[] table;\r
+//
+// System.Collections.SortedList.cs
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+// Duncan Mak (duncan@ximian.com)
+// Herve Poussineau (hpoussineau@fr.st
+//
+
+//
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// 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.Globalization;
+using System.Runtime.InteropServices;
+
+namespace System.Collections {
+
+ /// <summary>
+ /// Represents a collection of associated keys and values
+ /// that are sorted by the keys and are accessible by key
+ /// and by index.
+ /// </summary>
+ [Serializable]
+#if NET_2_0
+ [ComVisible(true)]
+#endif
+ public class SortedList : IDictionary, ICollection,
+ IEnumerable, ICloneable {
+
+
+ [Serializable]
+ internal struct Slot {
+ internal Object key;
+ internal Object value;
+ }
+
+ private readonly static int INITIAL_SIZE = 16;
+
+ private enum EnumeratorMode : int { KEY_MODE = 0, VALUE_MODE, ENTRY_MODE }
+
+ private int inUse;
+ private int modificationCount;
+ private Slot[] table;
private IComparer comparer;
- private int defaultCapacity;\r
-\r
- //\r
- // Constructors\r
- //\r
+ private int defaultCapacity;
+
+ //
+ // Constructors
+ //
public SortedList ()
- : this (null, INITIAL_SIZE)\r
- {\r
- }\r
-\r
- public SortedList (int initialCapacity)\r
- : this (null, initialCapacity)\r
- {\r
- }\r
-\r
- public SortedList (IComparer comparer, int initialCapacity)\r
- {\r
- if (initialCapacity < 0)\r
+ : this (null, INITIAL_SIZE)
+ {
+ }
+
+ public SortedList (int initialCapacity)
+ : this (null, initialCapacity)
+ {
+ }
+
+ public SortedList (IComparer comparer, int initialCapacity)
+ {
+ if (initialCapacity < 0)
throw new ArgumentOutOfRangeException ("initialCapacity");
if (initialCapacity == 0)
defaultCapacity = 0;
else
- defaultCapacity = INITIAL_SIZE;\r
-\r
- this.comparer = comparer;\r
- InitTable (initialCapacity, true);\r
- }\r
-\r
- public SortedList (IComparer comparer)\r
- {\r
- this.comparer = comparer;\r
- InitTable (INITIAL_SIZE, true);\r
- }\r
-\r
-\r
- public SortedList (IDictionary d) : this (d, null)\r
- {\r
- }\r
-\r
- public SortedList (IDictionary d, IComparer comparer)\r
- {\r
- if (d == null)\r
- throw new ArgumentNullException ("dictionary");\r
-\r
- InitTable (d.Count, true);\r
- this.comparer = comparer;\r
-\r
- IDictionaryEnumerator it = d.GetEnumerator ();\r
- while (it.MoveNext ()) {\r
- if (it.Key is IComparable) {\r
- Add (it.Key, it.Value);\r
- } else {\r
- throw new InvalidCastException("!IComparable");\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Properties\r
- //\r
-\r
- // ICollection\r
-\r
- public virtual int Count {\r
- get {\r
- return inUse;\r
- }\r
- }\r
-\r
- public virtual bool IsSynchronized {\r
- get {\r
- return false;\r
- }\r
- }\r
-\r
- public virtual Object SyncRoot {\r
- get {\r
- return this;\r
- }\r
- }\r
-\r
-\r
- // IDictionary\r
-\r
- public virtual bool IsFixedSize {\r
- get {\r
- return false;\r
- }\r
- }\r
-\r
-\r
- public virtual bool IsReadOnly {\r
- get {\r
- return false;\r
- }\r
- }\r
-\r
- public virtual ICollection Keys {\r
- get {\r
- return new ListKeys (this);\r
- }\r
- }\r
-\r
- public virtual ICollection Values {\r
- get {\r
- return new ListValues (this);\r
- }\r
- }\r
-\r
-\r
-\r
- public virtual Object this [Object key] {\r
- get {\r
- if (key == null)\r
- throw new ArgumentNullException();\r
- return GetImpl (key);\r
- }\r
- set {\r
- if (key == null)\r
- throw new ArgumentNullException();\r
- if (IsReadOnly)\r
- throw new NotSupportedException("SortedList is Read Only.");\r
- if (Find(key) < 0 && IsFixedSize)\r
- throw new NotSupportedException("Key not found and SortedList is fixed size.");\r
-\r
- PutImpl (key, value, true);\r
- }\r
- }\r
-\r
- public virtual int Capacity {\r
- get {\r
- return table.Length;\r
- }\r
-\r
- set {\r
- int current = this.table.Length;\r
-\r
+ defaultCapacity = INITIAL_SIZE;
+
+ this.comparer = comparer;
+ InitTable (initialCapacity, true);
+ }
+
+ public SortedList (IComparer comparer)
+ {
+ this.comparer = comparer;
+ InitTable (INITIAL_SIZE, true);
+ }
+
+
+ public SortedList (IDictionary d) : this (d, null)
+ {
+ }
+
+ // LAMESPEC: MSDN docs talk about an InvalidCastException but
+ // I wasn't able to duplicate such a case in the unit tests.
+ public SortedList (IDictionary d, IComparer comparer)
+ {
+ if (d == null)
+ throw new ArgumentNullException ("dictionary");
+
+ InitTable (d.Count, true);
+ this.comparer = comparer;
+
+ IDictionaryEnumerator it = d.GetEnumerator ();
+ while (it.MoveNext ()) {
+ Add (it.Key, it.Value);
+ }
+ }
+
+ //
+ // Properties
+ //
+
+ // ICollection
+
+ public virtual int Count {
+ get {
+ return inUse;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return false;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {
+ return this;
+ }
+ }
+
+
+ // IDictionary
+
+ public virtual bool IsFixedSize {
+ get {
+ return false;
+ }
+ }
+
+
+ public virtual bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public virtual ICollection Keys {
+ get {
+ return new ListKeys (this);
+ }
+ }
+
+ public virtual ICollection Values {
+ get {
+ return new ListValues (this);
+ }
+ }
+
+
+
+ public virtual Object this [Object key] {
+ get {
+ if (key == null)
+ throw new ArgumentNullException();
+ return GetImpl (key);
+ }
+ set {
+ if (key == null)
+ throw new ArgumentNullException();
+ if (IsReadOnly)
+ throw new NotSupportedException("SortedList is Read Only.");
+ if (Find(key) < 0 && IsFixedSize)
+ throw new NotSupportedException("Key not found and SortedList is fixed size.");
+
+ PutImpl (key, value, true);
+ }
+ }
+
+ public virtual int Capacity {
+ get {
+ return table.Length;
+ }
+
+ set {
+ int current = this.table.Length;
+
if (inUse > value) {
- throw new ArgumentOutOfRangeException("capacity too small");\r
+ throw new ArgumentOutOfRangeException("capacity too small");
}
else if (value == 0) {
// return to default size
Slot [] newTable = new Slot [defaultCapacity];
- Array.Copy (table, newTable, inUse);\r
- this.table = newTable;\r
+ Array.Copy (table, newTable, inUse);
+ this.table = newTable;
}
#if NET_1_0
else if (current > defaultCapacity && value < current) {
- Slot [] newTable = new Slot [defaultCapacity];\r
- Array.Copy (table, newTable, inUse);\r
- this.table = newTable;\r
+ Slot [] newTable = new Slot [defaultCapacity];
+ Array.Copy (table, newTable, inUse);
+ this.table = newTable;
}
#endif
- else if (value > inUse) {\r
- Slot [] newTable = new Slot [value];\r
- Array.Copy (table, newTable, inUse);\r
- this.table = newTable;\r
+ else if (value > inUse) {
+ Slot [] newTable = new Slot [value];
+ Array.Copy (table, newTable, inUse);
+ this.table = newTable;
}
- else if (value > current) {\r
- Slot [] newTable = new Slot [value];\r
- Array.Copy (table, newTable, current);\r
- this.table = newTable;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Public instance methods.\r
- //\r
-\r
- // IEnumerable\r
-\r
- IEnumerator IEnumerable.GetEnumerator ()\r
- {\r
- return new Enumerator (this, EnumeratorMode.ENTRY_MODE);\r
- }\r
-\r
-\r
- // IDictionary\r
-\r
- public virtual void Add (object key, object value)\r
- {\r
- PutImpl (key, value, false);\r
- }\r
-\r
-\r
- public virtual void Clear () \r
+ else if (value > current) {
+ Slot [] newTable = new Slot [value];
+ Array.Copy (table, newTable, current);
+ this.table = newTable;
+ }
+ }
+ }
+
+ //
+ // Public instance methods.
+ //
+
+ // IEnumerable
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return new Enumerator (this, EnumeratorMode.ENTRY_MODE);
+ }
+
+
+ // IDictionary
+
+ public virtual void Add (object key, object value)
+ {
+ PutImpl (key, value, false);
+ }
+
+
+ public virtual void Clear ()
+ {
+ defaultCapacity = INITIAL_SIZE;
+ this.table = new Slot [defaultCapacity];
+ inUse = 0;
+ modificationCount++;
+ }
+
+ public virtual bool Contains (object key)
+ {
+ if (null == key)
+ throw new ArgumentNullException();
+
+ try {
+ return (Find (key) >= 0);
+ } catch (Exception) {
+ throw new InvalidOperationException();
+ }
+ }
+
+
+ public virtual IDictionaryEnumerator GetEnumerator ()
+ {
+ return new Enumerator (this, EnumeratorMode.ENTRY_MODE);
+ }
+
+ public virtual void Remove (object key)
+ {
+ int i = IndexOfKey (key);
+ if (i >= 0) RemoveAt (i);
+ }
+
+
+ // ICollection
+
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ if (null == array)
+ throw new ArgumentNullException();
+
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException();
+
+ if (array.Rank > 1)
+ throw new ArgumentException("array is multi-dimensional");
+ if (arrayIndex >= array.Length)
+ throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length");
+ if (Count > (array.Length - arrayIndex))
+ throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array");
+
+ IDictionaryEnumerator it = GetEnumerator ();
+ int i = arrayIndex;
+
+ while (it.MoveNext ()) {
+ array.SetValue (it.Entry, i++);
+ }
+ }
+
+
+
+ // ICloneable
+
+ public virtual object Clone ()
{
- defaultCapacity = INITIAL_SIZE;\r
- this.table = new Slot [defaultCapacity];\r
- inUse = 0;\r
- modificationCount++;\r
- }\r
-\r
- public virtual bool Contains (object key)\r
- {\r
- if (null == key)\r
- throw new ArgumentNullException();\r
-\r
- try {\r
- return (Find (key) >= 0);\r
- } catch (Exception) {\r
- throw new InvalidOperationException();\r
- }\r
- }\r
-\r
-\r
- public virtual IDictionaryEnumerator GetEnumerator ()\r
- {\r
- return new Enumerator (this, EnumeratorMode.ENTRY_MODE);\r
- }\r
-\r
- public virtual void Remove (object key)\r
- {\r
- int i = IndexOfKey (key);\r
- if (i >= 0) RemoveAt (i);\r
- }\r
-\r
-\r
- // ICollection\r
-\r
- public virtual void CopyTo (Array array, int arrayIndex)\r
- {\r
- if (null == array)\r
- throw new ArgumentNullException();\r
-\r
- if (arrayIndex < 0)\r
- throw new ArgumentOutOfRangeException();\r
- \r
- if (array.Rank > 1)\r
- throw new ArgumentException("array is multi-dimensional");\r
- if (arrayIndex >= array.Length)\r
- throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length");\r
- if (Count > (array.Length - arrayIndex))\r
- throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array");\r
-\r
- IDictionaryEnumerator it = GetEnumerator ();\r
- int i = arrayIndex;\r
-\r
- while (it.MoveNext ()) {\r
- array.SetValue (it.Entry, i++);\r
- }\r
- }\r
-\r
-\r
-\r
- // ICloneable\r
-\r
- public virtual object Clone ()\r
- {\r
- SortedList sl = new SortedList (this, comparer);\r
- sl.modificationCount = this.modificationCount;\r
- return sl;\r
- }\r
-\r
-\r
-\r
-\r
- //\r
- // SortedList\r
- //\r
-\r
- public virtual IList GetKeyList ()\r
- {\r
- return new ListKeys (this);\r
- }\r
-\r
-\r
- public virtual IList GetValueList ()\r
- {\r
- return new ListValues (this);\r
- }\r
-\r
-\r
- public virtual void RemoveAt (int index)\r
- {\r
- Slot [] table = this.table;\r
- int cnt = Count;\r
- if (index >= 0 && index < cnt) {\r
- if (index != cnt - 1) {\r
- Array.Copy (table, index+1, table, index, cnt-1-index);\r
- } else {\r
- table [index].key = null;\r
- table [index].value = null;\r
- }\r
- --inUse;\r
- ++modificationCount;\r
- } else {\r
- throw new ArgumentOutOfRangeException("index out of range");\r
- }\r
- }\r
-\r
- public virtual int IndexOfKey (object key)\r
- {\r
- if (null == key)\r
- throw new ArgumentNullException();\r
-\r
- int indx = 0;\r
- try {\r
- indx = Find (key);\r
- } catch (Exception) {\r
- throw new InvalidOperationException();\r
- }\r
-\r
- return (indx | (indx >> 31));\r
- }\r
-\r
-\r
- public virtual int IndexOfValue (object value)\r
- {\r
- if (inUse == 0)\r
- return -1;\r
- \r
- for (int i = 0; i < inUse; i ++) {\r
- Slot current = this.table [i];\r
-\r
- if (Equals (current.value, value))\r
- return i;\r
- }\r
-\r
- return -1;\r
- }\r
-\r
-\r
- public virtual bool ContainsKey (object key)\r
- {\r
- if (null == key)\r
- throw new ArgumentNullException();\r
-\r
- try {\r
- return Contains (key); \r
- } catch (Exception) {\r
- throw new InvalidOperationException();\r
- }\r
- }\r
-\r
-\r
- public virtual bool ContainsValue (object value)\r
- {\r
- return IndexOfValue (value) >= 0;\r
- }\r
-\r
-\r
- public virtual object GetByIndex (int index)\r
- {\r
- if (index >= 0 && index < Count)\r
- return table [index].value;\r
-\r
- else \r
- throw new ArgumentOutOfRangeException("index out of range");\r
- }\r
-\r
-\r
- public virtual void SetByIndex (int index, object value)\r
- {\r
- if (index >= 0 && index < Count)\r
- table [index].value = value;\r
-\r
- else\r
- throw new ArgumentOutOfRangeException("index out of range");\r
- }\r
-\r
-\r
- public virtual object GetKey (int index)\r
- {\r
- if (index >= 0 && index < Count)\r
- return table [index].key;\r
-\r
- else\r
- throw new ArgumentOutOfRangeException("index out of range");\r
- }\r
-\r
- public static SortedList Synchronized (SortedList list)\r
- {\r
- if (list == null)\r
- throw new ArgumentNullException (Locale.GetText ("Base list is null."));\r
-\r
- return new SynchedSortedList (list);\r
- }\r
-\r
- public virtual void TrimToSize ()\r
- {\r
- // From Beta2:\r
- // Trimming an empty SortedList sets the capacity\r
- // of the SortedList to the default capacity,\r
- // not zero.\r
- if (Count == 0)\r
- Resize (defaultCapacity, false);\r
- else\r
- Resize (Count, true);\r
- }\r
-\r
-\r
- //\r
- // Private methods\r
- //\r
-\r
-\r
- private void Resize (int n, bool copy)\r
- {\r
- Slot [] table = this.table;\r
- Slot [] newTable = new Slot [n];\r
- if (copy) Array.Copy (table, 0, newTable, 0, n);\r
- this.table = newTable;\r
- }\r
-\r
-\r
- private void EnsureCapacity (int n, int free)\r
- {\r
- Slot [] table = this.table;\r
- Slot [] newTable = null;\r
- int cap = Capacity;\r
- bool gap = (free >=0 && free < Count);\r
-\r
- if (n > cap) {\r
- newTable = new Slot [n << 1];\r
- }\r
-\r
- if (newTable != null) {\r
- if (gap) {\r
- int copyLen = free;\r
- if (copyLen > 0) {\r
- Array.Copy (table, 0, newTable, 0, copyLen);\r
- }\r
- copyLen = Count - free;\r
- if (copyLen > 0) {\r
- Array.Copy (table, free, newTable, free+1, copyLen);\r
- }\r
- } else {\r
- // Just a resizing, copy the entire table.\r
- Array.Copy (table, newTable, Count);\r
- }\r
- this.table = newTable;\r
- } else if (gap) {\r
- Array.Copy (table, free, table, free+1, Count - free);\r
- }\r
- }\r
-\r
-\r
- private void PutImpl (object key, object value, bool overwrite)\r
- {\r
- if (key == null)\r
- throw new ArgumentNullException ("null key");\r
-\r
- Slot [] table = this.table;\r
-\r
- int freeIndx = -1;\r
-\r
- try {\r
- freeIndx = Find (key);\r
- } catch (Exception) {\r
- throw new InvalidOperationException();\r
- }\r
-\r
- if (freeIndx >= 0) {\r
- if (!overwrite)\r
- throw new ArgumentException("element already exists");\r
-\r
- table [freeIndx].value = value;\r
- return;\r
- }\r
-\r
- freeIndx = ~freeIndx;\r
-\r
- if (freeIndx > Capacity + 1)\r
- throw new Exception ("SortedList::internal error ("+key+", "+value+") at ["+freeIndx+"]");\r
-\r
-\r
- EnsureCapacity (Count+1, freeIndx);\r
-\r
- table = this.table;\r
- table [freeIndx].key = key;\r
- table [freeIndx].value = value;\r
-\r
- ++inUse;\r
- ++modificationCount;\r
-\r
- }\r
-\r
-\r
- private object GetImpl (object key)\r
- {\r
- int i = Find (key);\r
-\r
- if (i >= 0)\r
- return table [i].value;\r
- else\r
- return null;\r
- }\r
-\r
- private void InitTable (int capacity)\r
- {\r
- InitTable (capacity, false);\r
- }\r
-\r
+ SortedList sl = new SortedList (this, comparer);
+ sl.modificationCount = this.modificationCount;
+ return sl;
+ }
+
+
+
+
+ //
+ // SortedList
+ //
+
+ public virtual IList GetKeyList ()
+ {
+ return new ListKeys (this);
+ }
+
+
+ public virtual IList GetValueList ()
+ {
+ return new ListValues (this);
+ }
+
+
+ public virtual void RemoveAt (int index)
+ {
+ Slot [] table = this.table;
+ int cnt = Count;
+ if (index >= 0 && index < cnt) {
+ if (index != cnt - 1) {
+ Array.Copy (table, index+1, table, index, cnt-1-index);
+ } else {
+ table [index].key = null;
+ table [index].value = null;
+ }
+ --inUse;
+ ++modificationCount;
+ } else {
+ throw new ArgumentOutOfRangeException("index out of range");
+ }
+ }
+
+ public virtual int IndexOfKey (object key)
+ {
+ if (null == key)
+ throw new ArgumentNullException();
+
+ int indx = 0;
+ try {
+ indx = Find (key);
+ } catch (Exception) {
+ throw new InvalidOperationException();
+ }
+
+ return (indx | (indx >> 31));
+ }
+
+
+ public virtual int IndexOfValue (object value)
+ {
+ if (inUse == 0)
+ return -1;
+
+ for (int i = 0; i < inUse; i ++) {
+ Slot current = this.table [i];
+
+ if (Equals (value, current.value))
+ return i;
+ }
+
+ return -1;
+ }
+
+
+ public virtual bool ContainsKey (object key)
+ {
+ if (null == key)
+ throw new ArgumentNullException();
+
+ try {
+ return Contains (key);
+ } catch (Exception) {
+ throw new InvalidOperationException();
+ }
+ }
+
+
+ public virtual bool ContainsValue (object value)
+ {
+ return IndexOfValue (value) >= 0;
+ }
+
+
+ public virtual object GetByIndex (int index)
+ {
+ if (index >= 0 && index < Count)
+ return table [index].value;
+
+ else
+ throw new ArgumentOutOfRangeException("index out of range");
+ }
+
+
+ public virtual void SetByIndex (int index, object value)
+ {
+ if (index >= 0 && index < Count)
+ table [index].value = value;
+
+ else
+ throw new ArgumentOutOfRangeException("index out of range");
+ }
+
+
+ public virtual object GetKey (int index)
+ {
+ if (index >= 0 && index < Count)
+ return table [index].key;
+
+ else
+ throw new ArgumentOutOfRangeException("index out of range");
+ }
+
+ public static SortedList Synchronized (SortedList list)
+ {
+ if (list == null)
+ throw new ArgumentNullException (Locale.GetText ("Base list is null."));
+
+ return new SynchedSortedList (list);
+ }
+
+ public virtual void TrimToSize ()
+ {
+ // From Beta2:
+ // Trimming an empty SortedList sets the capacity
+ // of the SortedList to the default capacity,
+ // not zero.
+ if (Count == 0)
+ Resize (defaultCapacity, false);
+ else
+ Resize (Count, true);
+ }
+
+
+ //
+ // Private methods
+ //
+
+
+ private void Resize (int n, bool copy)
+ {
+ Slot [] table = this.table;
+ Slot [] newTable = new Slot [n];
+ if (copy) Array.Copy (table, 0, newTable, 0, n);
+ this.table = newTable;
+ }
+
+
+ private void EnsureCapacity (int n, int free)
+ {
+ Slot [] table = this.table;
+ Slot [] newTable = null;
+ int cap = Capacity;
+ bool gap = (free >=0 && free < Count);
+
+ if (n > cap) {
+ newTable = new Slot [n << 1];
+ }
+
+ if (newTable != null) {
+ if (gap) {
+ int copyLen = free;
+ if (copyLen > 0) {
+ Array.Copy (table, 0, newTable, 0, copyLen);
+ }
+ copyLen = Count - free;
+ if (copyLen > 0) {
+ Array.Copy (table, free, newTable, free+1, copyLen);
+ }
+ } else {
+ // Just a resizing, copy the entire table.
+ Array.Copy (table, newTable, Count);
+ }
+ this.table = newTable;
+ } else if (gap) {
+ Array.Copy (table, free, table, free+1, Count - free);
+ }
+ }
+
+
+ private void PutImpl (object key, object value, bool overwrite)
+ {
+ if (key == null)
+ throw new ArgumentNullException ("null key");
+
+ Slot [] table = this.table;
+
+ int freeIndx = -1;
+
+ try {
+ freeIndx = Find (key);
+ } catch (Exception) {
+ throw new InvalidOperationException();
+ }
+
+ if (freeIndx >= 0) {
+ if (!overwrite) {
+ string msg = Locale.GetText ("Key '{0}' already exists in list.", key);
+ throw new ArgumentException (msg);
+ }
+
+ table [freeIndx].value = value;
+ ++modificationCount;
+ return;
+ }
+
+ freeIndx = ~freeIndx;
+
+ if (freeIndx > Capacity + 1)
+ throw new Exception ("SortedList::internal error ("+key+", "+value+") at ["+freeIndx+"]");
+
+
+ EnsureCapacity (Count+1, freeIndx);
+
+ table = this.table;
+ table [freeIndx].key = key;
+ table [freeIndx].value = value;
+
+ ++inUse;
+ ++modificationCount;
+
+ }
+
+
+ private object GetImpl (object key)
+ {
+ int i = Find (key);
+
+ if (i >= 0)
+ return table [i].value;
+ else
+ return null;
+ }
+
private void InitTable (int capacity, bool forceSize)
- {\r
+ {
if (!forceSize && (capacity < defaultCapacity))
- capacity = defaultCapacity;\r
- this.table = new Slot [capacity];\r
- this.inUse = 0;\r
- this.modificationCount = 0;\r
- }\r
-\r
- private void CopyToArray (Array arr, int i, \r
- EnumeratorMode mode)\r
- {\r
- if (arr == null)\r
- throw new ArgumentNullException ("arr");\r
-\r
- if (i < 0 || i + this.Count > arr.Length)\r
- throw new ArgumentOutOfRangeException ("i");\r
- \r
- IEnumerator it = new Enumerator (this, mode);\r
-\r
- while (it.MoveNext ()) {\r
- arr.SetValue (it.Current, i++);\r
- }\r
- }\r
-\r
-\r
- private int Find (object key)\r
- {\r
- Slot [] table = this.table;\r
- int len = Count;\r
-\r
- if (len == 0) return ~0;\r
-\r
- IComparer comparer = (this.comparer == null)\r
- ? Comparer.Default\r
- : this.comparer;\r
-\r
- int left = 0;\r
- int right = len-1;\r
-\r
- while (left <= right) {\r
- int guess = (left + right) >> 1;\r
-\r
- int cmp = comparer.Compare (key, table[guess].key);\r
- if (cmp == 0) return guess;\r
-\r
- if (cmp > 0) left = guess+1;\r
- else right = guess-1;\r
- }\r
-\r
- return ~left;\r
- }\r
-\r
-\r
-\r
- //\r
- // Inner classes\r
- //\r
-\r
-\r
- private sealed class Enumerator : ICloneable, IDictionaryEnumerator, IEnumerator {\r
-\r
- private SortedList host;\r
- private int stamp;\r
- private int pos;\r
- private int size;\r
- private EnumeratorMode mode;\r
-\r
- private object currentKey;\r
- private object currentValue;\r
-\r
- bool invalid = false;\r
-\r
- private readonly static string xstr = "SortedList.Enumerator: snapshot out of sync.";\r
-\r
- public Enumerator (SortedList host, EnumeratorMode mode)\r
- {\r
- this.host = host;\r
- stamp = host.modificationCount;\r
- size = host.Count;\r
- this.mode = mode;\r
- Reset ();\r
- }\r
-\r
- public Enumerator (SortedList host)\r
- : this (host, EnumeratorMode.ENTRY_MODE)\r
- {\r
- }\r
-\r
- public void Reset ()\r
- {\r
- if (host.modificationCount != stamp || invalid)\r
- throw new InvalidOperationException (xstr);\r
-\r
- pos = -1;\r
- currentKey = null;\r
- currentValue = null;\r
- }\r
-\r
- public bool MoveNext ()\r
- {\r
- if (host.modificationCount != stamp || invalid)\r
- throw new InvalidOperationException (xstr);\r
-\r
- Slot [] table = host.table;\r
-\r
- if (++pos < size) {\r
- Slot entry = table [pos];\r
-\r
- currentKey = entry.key;\r
- currentValue = entry.value;\r
- return true;\r
- }\r
-\r
- currentKey = null;\r
- currentValue = null;\r
- return false;\r
- }\r
-\r
- public DictionaryEntry Entry\r
- {\r
- get {\r
- if (invalid || pos >= size || pos == -1)\r
- throw new InvalidOperationException (xstr);\r
- \r
- return new DictionaryEntry (currentKey,\r
- currentValue);\r
- }\r
- }\r
-\r
- public Object Key {\r
- get {\r
- if (invalid || pos >= size || pos == -1)\r
- throw new InvalidOperationException (xstr);\r
- return currentKey;\r
- }\r
- }\r
-\r
- public Object Value {\r
- get {\r
- if (invalid || pos >= size || pos == -1)\r
- throw new InvalidOperationException (xstr);\r
- return currentValue;\r
- }\r
- }\r
-\r
- public Object Current {\r
- get {\r
- if (invalid || pos >= size || pos == -1)\r
- throw new InvalidOperationException (xstr);\r
-\r
- switch (mode) {\r
- case EnumeratorMode.KEY_MODE:\r
- return currentKey;\r
- case EnumeratorMode.VALUE_MODE:\r
- return currentValue;\r
- case EnumeratorMode.ENTRY_MODE:\r
- return this.Entry;\r
-\r
- default:\r
- throw new NotSupportedException (mode + " is not a supported mode.");\r
- }\r
- }\r
+ capacity = defaultCapacity;
+ this.table = new Slot [capacity];
+ this.inUse = 0;
+ this.modificationCount = 0;
+ }
+
+ private void CopyToArray (Array arr, int i,
+ EnumeratorMode mode)
+ {
+ if (arr == null)
+ throw new ArgumentNullException ("arr");
+
+ if (i < 0 || i + this.Count > arr.Length)
+ throw new ArgumentOutOfRangeException ("i");
+
+ IEnumerator it = new Enumerator (this, mode);
+
+ while (it.MoveNext ()) {
+ arr.SetValue (it.Current, i++);
+ }
+ }
+
+
+ private int Find (object key)
+ {
+ Slot [] table = this.table;
+ int len = Count;
+
+ if (len == 0) return ~0;
+
+ IComparer comparer = (this.comparer == null)
+ ? Comparer.Default
+ : this.comparer;
+
+ int left = 0;
+ int right = len-1;
+
+ while (left <= right) {
+ int guess = (left + right) >> 1;
+
+ int cmp = comparer.Compare (key, table[guess].key);
+ if (cmp == 0) return guess;
+
+ if (cmp > 0) left = guess+1;
+ else right = guess-1;
+ }
+
+ return ~left;
+ }
+
+
+
+ //
+ // Inner classes
+ //
+
+
+ private sealed class Enumerator : ICloneable, IDictionaryEnumerator, IEnumerator {
+
+ private SortedList host;
+ private int stamp;
+ private int pos;
+ private int size;
+ private EnumeratorMode mode;
+
+ private object currentKey;
+ private object currentValue;
+
+ bool invalid = false;
+
+ private readonly static string xstr = "SortedList.Enumerator: snapshot out of sync.";
+
+ public Enumerator (SortedList host, EnumeratorMode mode)
+ {
+ this.host = host;
+ stamp = host.modificationCount;
+ size = host.Count;
+ this.mode = mode;
+ Reset ();
+ }
+
+ public Enumerator (SortedList host)
+ : this (host, EnumeratorMode.ENTRY_MODE)
+ {
+ }
+
+ public void Reset ()
+ {
+ if (host.modificationCount != stamp || invalid)
+ throw new InvalidOperationException (xstr);
+
+ pos = -1;
+ currentKey = null;
+ currentValue = null;
+ }
+
+ public bool MoveNext ()
+ {
+ if (host.modificationCount != stamp || invalid)
+ throw new InvalidOperationException (xstr);
+
+ Slot [] table = host.table;
+
+ if (++pos < size) {
+ Slot entry = table [pos];
+
+ currentKey = entry.key;
+ currentValue = entry.value;
+ return true;
+ }
+
+ currentKey = null;
+ currentValue = null;
+ return false;
+ }
+
+ public DictionaryEntry Entry
+ {
+ get {
+ if (invalid || pos >= size || pos == -1)
+ throw new InvalidOperationException (xstr);
+
+ return new DictionaryEntry (currentKey,
+ currentValue);
+ }
+ }
+
+ public Object Key {
+ get {
+ if (invalid || pos >= size || pos == -1)
+ throw new InvalidOperationException (xstr);
+ return currentKey;
+ }
+ }
+
+ public Object Value {
+ get {
+ if (invalid || pos >= size || pos == -1)
+ throw new InvalidOperationException (xstr);
+ return currentValue;
+ }
+ }
+
+ public Object Current {
+ get {
+ if (invalid || pos >= size || pos == -1)
+ throw new InvalidOperationException (xstr);
+
+ switch (mode) {
+ case EnumeratorMode.KEY_MODE:
+ return currentKey;
+ case EnumeratorMode.VALUE_MODE:
+ return currentValue;
+ case EnumeratorMode.ENTRY_MODE:
+ return this.Entry;
+
+ default:
+ throw new NotSupportedException (mode + " is not a supported mode.");
+ }
+ }
}
// ICloneable
e.currentValue = currentValue;
e.invalid = invalid;
return e;
- }\r
- }\r
-\r
-\r
- private class ListKeys : IList, IEnumerable {\r
-\r
- private SortedList host;\r
-\r
-\r
- public ListKeys (SortedList host)\r
- {\r
- if (host == null)\r
- throw new ArgumentNullException ();\r
-\r
- this.host = host;\r
- }\r
-\r
- //\r
- // ICollection\r
- //\r
-\r
- public virtual int Count {\r
- get {\r
- return host.Count;\r
- }\r
- }\r
-\r
- public virtual bool IsSynchronized {\r
- get {\r
- return host.IsSynchronized;\r
- }\r
- }\r
-\r
- public virtual Object SyncRoot {\r
- get {\r
- return host.SyncRoot;\r
- }\r
- }\r
-\r
- public virtual void CopyTo (Array array, int arrayIndex)\r
- {\r
- host.CopyToArray (array, arrayIndex, EnumeratorMode.KEY_MODE);\r
- }\r
-\r
-\r
- //\r
- // IList\r
- //\r
-\r
- public virtual bool IsFixedSize {\r
- get {\r
- return true;\r
- }\r
- }\r
-\r
- public virtual bool IsReadOnly {\r
- get {\r
- return true;\r
- }\r
- }\r
-\r
-\r
- public virtual object this [int index] {\r
- get {\r
- return host.GetKey (index);\r
- }\r
- set {\r
- throw new NotSupportedException("attempt to modify a key");\r
- }\r
- }\r
-\r
- public virtual int Add (object value)\r
- {\r
- throw new NotSupportedException("IList::Add not supported");\r
- }\r
-\r
- public virtual void Clear ()\r
- {\r
- throw new NotSupportedException("IList::Clear not supported");\r
- }\r
-\r
- public virtual bool Contains (object key)\r
- {\r
- return host.Contains (key);\r
- }\r
-\r
-\r
- public virtual int IndexOf (object key)\r
- {\r
- return host.IndexOfKey (key);\r
- }\r
-\r
-\r
- public virtual void Insert (int index, object value)\r
- {\r
- throw new NotSupportedException("IList::Insert not supported");\r
- }\r
-\r
-\r
- public virtual void Remove (object value)\r
- {\r
- throw new NotSupportedException("IList::Remove not supported");\r
- }\r
-\r
-\r
- public virtual void RemoveAt (int index)\r
- {\r
- throw new NotSupportedException("IList::RemoveAt not supported");\r
- }\r
-\r
-\r
- //\r
- // IEnumerable\r
- //\r
-\r
- public virtual IEnumerator GetEnumerator ()\r
- {\r
- return new SortedList.Enumerator (host, EnumeratorMode.KEY_MODE);\r
- }\r
-\r
-\r
- }\r
-\r
-\r
- private class ListValues : IList, IEnumerable {\r
-\r
- private SortedList host;\r
-\r
-\r
- public ListValues (SortedList host)\r
- {\r
- if (host == null)\r
- throw new ArgumentNullException ();\r
-\r
- this.host = host;\r
- }\r
-\r
- //\r
- // ICollection\r
- //\r
-\r
- public virtual int Count {\r
- get {\r
- return host.Count;\r
- }\r
- }\r
-\r
- public virtual bool IsSynchronized {\r
- get {\r
- return host.IsSynchronized;\r
- }\r
- }\r
-\r
- public virtual Object SyncRoot {\r
- get {\r
- return host.SyncRoot;\r
- }\r
- }\r
-\r
- public virtual void CopyTo (Array array, int arrayIndex)\r
- {\r
- host.CopyToArray (array, arrayIndex, EnumeratorMode.VALUE_MODE);\r
- }\r
-\r
-\r
- //\r
- // IList\r
- //\r
-\r
- public virtual bool IsFixedSize {\r
- get {\r
- return true;\r
- }\r
- }\r
-\r
- public virtual bool IsReadOnly {\r
- get {\r
- return true;\r
- }\r
- }\r
-\r
-\r
- [MonoTODO]\r
- public virtual object this [int index] {\r
- get {\r
- return host.GetByIndex (index);\r
- }\r
- set {\r
- // FIXME: It seems (according to tests)\r
- // that modifications are allowed\r
- // in Beta2.\r
- // ? host.SetByIndex (index, value);\r
- throw new NotSupportedException("attempt to modify a value");\r
- }\r
- }\r
-\r
- public virtual int Add (object value)\r
- {\r
- throw new NotSupportedException("IList::Add not supported");\r
- }\r
-\r
- public virtual void Clear ()\r
- {\r
- throw new NotSupportedException("IList::Clear not supported");\r
- }\r
-\r
- public virtual bool Contains (object value)\r
- {\r
- return host.ContainsValue (value);\r
- }\r
-\r
-\r
- public virtual int IndexOf (object value)\r
- {\r
- return host.IndexOfValue (value);\r
- }\r
-\r
-\r
- public virtual void Insert (int index, object value)\r
- {\r
- throw new NotSupportedException("IList::Insert not supported");\r
- }\r
-\r
-\r
- public virtual void Remove (object value)\r
- {\r
- throw new NotSupportedException("IList::Remove not supported");\r
- }\r
-\r
-\r
- public virtual void RemoveAt (int index)\r
- {\r
- throw new NotSupportedException("IList::RemoveAt not supported");\r
- }\r
-\r
-\r
- //\r
- // IEnumerable\r
- //\r
-\r
- public virtual IEnumerator GetEnumerator ()\r
- {\r
- return new SortedList.Enumerator (host, EnumeratorMode.VALUE_MODE);\r
- }\r
-\r
- }\r
-\r
- private class SynchedSortedList : SortedList {\r
-\r
- private SortedList host;\r
-\r
- public SynchedSortedList (SortedList host)\r
- {\r
- if (host == null)\r
- throw new ArgumentNullException ();\r
- this.host = host;\r
- }\r
-
- public override int Capacity {\r
- get {\r
- lock (host.SyncRoot) {\r
+ }
+ }
+
+
+ private class ListKeys : IList, IEnumerable {
+
+ private SortedList host;
+
+
+ public ListKeys (SortedList host)
+ {
+ if (host == null)
+ throw new ArgumentNullException ();
+
+ this.host = host;
+ }
+
+ //
+ // ICollection
+ //
+
+ public virtual int Count {
+ get {
+ return host.Count;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return host.IsSynchronized;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {
+ return host.SyncRoot;
+ }
+ }
+
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ host.CopyToArray (array, arrayIndex, EnumeratorMode.KEY_MODE);
+ }
+
+
+ //
+ // IList
+ //
+
+ public virtual bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ public virtual bool IsReadOnly {
+ get {
+ return true;
+ }
+ }
+
+
+ public virtual object this [int index] {
+ get {
+ return host.GetKey (index);
+ }
+ set {
+ throw new NotSupportedException("attempt to modify a key");
+ }
+ }
+
+ public virtual int Add (object value)
+ {
+ throw new NotSupportedException("IList::Add not supported");
+ }
+
+ public virtual void Clear ()
+ {
+ throw new NotSupportedException("IList::Clear not supported");
+ }
+
+ public virtual bool Contains (object key)
+ {
+ return host.Contains (key);
+ }
+
+
+ public virtual int IndexOf (object key)
+ {
+ return host.IndexOfKey (key);
+ }
+
+
+ public virtual void Insert (int index, object value)
+ {
+ throw new NotSupportedException("IList::Insert not supported");
+ }
+
+
+ public virtual void Remove (object value)
+ {
+ throw new NotSupportedException("IList::Remove not supported");
+ }
+
+
+ public virtual void RemoveAt (int index)
+ {
+ throw new NotSupportedException("IList::RemoveAt not supported");
+ }
+
+
+ //
+ // IEnumerable
+ //
+
+ public virtual IEnumerator GetEnumerator ()
+ {
+ return new SortedList.Enumerator (host, EnumeratorMode.KEY_MODE);
+ }
+
+
+ }
+
+
+ private class ListValues : IList, IEnumerable {
+
+ private SortedList host;
+
+
+ public ListValues (SortedList host)
+ {
+ if (host == null)
+ throw new ArgumentNullException ();
+
+ this.host = host;
+ }
+
+ //
+ // ICollection
+ //
+
+ public virtual int Count {
+ get {
+ return host.Count;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return host.IsSynchronized;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {
+ return host.SyncRoot;
+ }
+ }
+
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ host.CopyToArray (array, arrayIndex, EnumeratorMode.VALUE_MODE);
+ }
+
+
+ //
+ // IList
+ //
+
+ public virtual bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ public virtual bool IsReadOnly {
+ get {
+ return true;
+ }
+ }
+
+
+ [MonoTODO]
+ public virtual object this [int index] {
+ get {
+ return host.GetByIndex (index);
+ }
+ set {
+ // FIXME: It seems (according to tests)
+ // that modifications are allowed
+ // in Beta2.
+ // ? host.SetByIndex (index, value);
+ throw new NotSupportedException("attempt to modify a value");
+ }
+ }
+
+ public virtual int Add (object value)
+ {
+ throw new NotSupportedException("IList::Add not supported");
+ }
+
+ public virtual void Clear ()
+ {
+ throw new NotSupportedException("IList::Clear not supported");
+ }
+
+ public virtual bool Contains (object value)
+ {
+ return host.ContainsValue (value);
+ }
+
+
+ public virtual int IndexOf (object value)
+ {
+ return host.IndexOfValue (value);
+ }
+
+
+ public virtual void Insert (int index, object value)
+ {
+ throw new NotSupportedException("IList::Insert not supported");
+ }
+
+
+ public virtual void Remove (object value)
+ {
+ throw new NotSupportedException("IList::Remove not supported");
+ }
+
+
+ public virtual void RemoveAt (int index)
+ {
+ throw new NotSupportedException("IList::RemoveAt not supported");
+ }
+
+
+ //
+ // IEnumerable
+ //
+
+ public virtual IEnumerator GetEnumerator ()
+ {
+ return new SortedList.Enumerator (host, EnumeratorMode.VALUE_MODE);
+ }
+
+ }
+
+ private class SynchedSortedList : SortedList {
+
+ private SortedList host;
+
+ public SynchedSortedList (SortedList host)
+ {
+ if (host == null)
+ throw new ArgumentNullException ();
+ this.host = host;
+ }
+
+ public override int Capacity {
+ get {
+ lock (host.SyncRoot) {
return host.Capacity;
- }\r
- }\r
- set {\r
- lock (host.SyncRoot) {\r
+ }
+ }
+ set {
+ lock (host.SyncRoot) {
host.Capacity = value;
- }\r
- }\r
- }\r
-\r
- // ICollection\r
-\r
- public override int Count {\r
- get {\r
- return host.Count;\r
- }\r
- }\r
-\r
- public override bool IsSynchronized {\r
- get {\r
- return true;\r
- }\r
- }\r
-\r
- public override Object SyncRoot {\r
- get {\r
- return host.SyncRoot;\r
- }\r
- }\r
-\r
-\r
-\r
- // IDictionary\r
-\r
- public override bool IsFixedSize {\r
- get {\r
- return host.IsFixedSize;\r
- } \r
- }\r
-\r
-\r
- public override bool IsReadOnly {\r
- get {\r
- return host.IsReadOnly;\r
- }\r
- }\r
-\r
- public override ICollection Keys {\r
- get {\r
- ICollection keys = null;\r
- lock (host.SyncRoot) {\r
- keys = host.Keys;\r
- }\r
- return keys;\r
- }\r
- }\r
-\r
- public override ICollection Values {\r
- get {\r
- ICollection vals = null;\r
- lock (host.SyncRoot) {\r
- vals = host.Values;\r
- }\r
- return vals;\r
- }\r
- }\r
-\r
-\r
-\r
- public override Object this [object key] {\r
- get {\r
- lock (host.SyncRoot) {\r
- return host.GetImpl (key);\r
- }\r
- }\r
- set {\r
- lock (host.SyncRoot) {\r
- host.PutImpl (key, value, true);\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
- // ICollection\r
-\r
- public override void CopyTo (Array array, int arrayIndex)\r
- {\r
- lock (host.SyncRoot) {\r
- host.CopyTo (array, arrayIndex);\r
- }\r
- }\r
-\r
-\r
- // IDictionary\r
-\r
- public override void Add (object key, object value)\r
- {\r
- lock (host.SyncRoot) {\r
- host.PutImpl (key, value, false);\r
- }\r
- }\r
-\r
- public override void Clear () \r
- {\r
- lock (host.SyncRoot) {\r
- host.Clear ();\r
- }\r
- }\r
-\r
- public override bool Contains (object key)\r
- {\r
- lock (host.SyncRoot) {\r
- return (host.Find (key) >= 0);\r
- }\r
- }\r
-\r
- public override IDictionaryEnumerator GetEnumerator ()\r
- {\r
- lock (host.SyncRoot) {\r
- return host.GetEnumerator();\r
- }\r
- }\r
-\r
- public override void Remove (object key)\r
- {\r
- lock (host.SyncRoot) {\r
- host.Remove (key);\r
- }\r
- }\r
-\r
-\r
-\r
- public override bool ContainsKey (object key)\r
- {\r
- lock (host.SyncRoot) {\r
- return host.Contains (key);\r
- }\r
- }\r
-\r
- public override bool ContainsValue (object value)\r
- {\r
- lock (host.SyncRoot) {\r
- return host.ContainsValue (value);\r
- }\r
- }\r
-\r
-\r
- // ICloneable\r
-\r
- public override object Clone ()\r
- {\r
- lock (host.SyncRoot) {\r
- return (host.Clone () as SortedList);\r
- }\r
- }\r
-\r
-\r
-\r
- //\r
- // SortedList overrides\r
- //\r
-\r
- public override Object GetByIndex (int index)\r
- {\r
- lock (host.SyncRoot) {\r
- return host.GetByIndex (index);\r
- }\r
- }\r
-\r
- public override Object GetKey (int index)\r
- {\r
- lock (host.SyncRoot) {\r
- return host.GetKey (index);\r
- }\r
- }\r
-\r
- public override IList GetKeyList ()\r
- {\r
- lock (host.SyncRoot) {\r
- return new ListKeys (host);\r
- }\r
- }\r
-\r
-\r
- public override IList GetValueList ()\r
- {\r
- lock (host.SyncRoot) {\r
- return new ListValues (host);\r
- }\r
- }\r
-\r
- public override void RemoveAt (int index)\r
- {\r
- lock (host.SyncRoot) {\r
- host.RemoveAt (index);\r
- }\r
- }\r
-\r
- public override int IndexOfKey (object key)\r
- {\r
- lock (host.SyncRoot) {\r
- return host.IndexOfKey (key);\r
- }\r
- }\r
-\r
- public override int IndexOfValue (Object val)\r
- {\r
- lock (host.SyncRoot) {\r
- return host.IndexOfValue (val);\r
- }\r
- }\r
-\r
- public override void SetByIndex (int index, object value)\r
- {\r
- lock (host.SyncRoot) {\r
- host.SetByIndex (index, value);\r
- }\r
- }\r
-\r
- public override void TrimToSize()\r
- {\r
- lock (host.SyncRoot) {\r
- host.TrimToSize();\r
- }\r
- }\r
-\r
-\r
- } // SynchedSortedList\r
-\r
- } // SortedList\r
-\r
+ }
+ }
+ }
+
+ // ICollection
+
+ public override int Count {
+ get {
+ return host.Count;
+ }
+ }
+
+ public override bool IsSynchronized {
+ get {
+ return true;
+ }
+ }
+
+ public override Object SyncRoot {
+ get {
+ return host.SyncRoot;
+ }
+ }
+
+
+
+ // IDictionary
+
+ public override bool IsFixedSize {
+ get {
+ return host.IsFixedSize;
+ }
+ }
+
+
+ public override bool IsReadOnly {
+ get {
+ return host.IsReadOnly;
+ }
+ }
+
+ public override ICollection Keys {
+ get {
+ ICollection keys = null;
+ lock (host.SyncRoot) {
+ keys = host.Keys;
+ }
+ return keys;
+ }
+ }
+
+ public override ICollection Values {
+ get {
+ ICollection vals = null;
+ lock (host.SyncRoot) {
+ vals = host.Values;
+ }
+ return vals;
+ }
+ }
+
+
+
+ public override Object this [object key] {
+ get {
+ lock (host.SyncRoot) {
+ return host.GetImpl (key);
+ }
+ }
+ set {
+ lock (host.SyncRoot) {
+ host.PutImpl (key, value, true);
+ }
+ }
+ }
+
+
+
+ // ICollection
+
+ public override void CopyTo (Array array, int arrayIndex)
+ {
+ lock (host.SyncRoot) {
+ host.CopyTo (array, arrayIndex);
+ }
+ }
+
+
+ // IDictionary
+
+ public override void Add (object key, object value)
+ {
+ lock (host.SyncRoot) {
+ host.PutImpl (key, value, false);
+ }
+ }
+
+ public override void Clear ()
+ {
+ lock (host.SyncRoot) {
+ host.Clear ();
+ }
+ }
+
+ public override bool Contains (object key)
+ {
+ lock (host.SyncRoot) {
+ return (host.Find (key) >= 0);
+ }
+ }
+
+ public override IDictionaryEnumerator GetEnumerator ()
+ {
+ lock (host.SyncRoot) {
+ return host.GetEnumerator();
+ }
+ }
+
+ public override void Remove (object key)
+ {
+ lock (host.SyncRoot) {
+ host.Remove (key);
+ }
+ }
+
+
+
+ public override bool ContainsKey (object key)
+ {
+ lock (host.SyncRoot) {
+ return host.Contains (key);
+ }
+ }
+
+ public override bool ContainsValue (object value)
+ {
+ lock (host.SyncRoot) {
+ return host.ContainsValue (value);
+ }
+ }
+
+
+ // ICloneable
+
+ public override object Clone ()
+ {
+ lock (host.SyncRoot) {
+ return (host.Clone () as SortedList);
+ }
+ }
+
+
+
+ //
+ // SortedList overrides
+ //
+
+ public override Object GetByIndex (int index)
+ {
+ lock (host.SyncRoot) {
+ return host.GetByIndex (index);
+ }
+ }
+
+ public override Object GetKey (int index)
+ {
+ lock (host.SyncRoot) {
+ return host.GetKey (index);
+ }
+ }
+
+ public override IList GetKeyList ()
+ {
+ lock (host.SyncRoot) {
+ return new ListKeys (host);
+ }
+ }
+
+
+ public override IList GetValueList ()
+ {
+ lock (host.SyncRoot) {
+ return new ListValues (host);
+ }
+ }
+
+ public override void RemoveAt (int index)
+ {
+ lock (host.SyncRoot) {
+ host.RemoveAt (index);
+ }
+ }
+
+ public override int IndexOfKey (object key)
+ {
+ lock (host.SyncRoot) {
+ return host.IndexOfKey (key);
+ }
+ }
+
+ public override int IndexOfValue (Object val)
+ {
+ lock (host.SyncRoot) {
+ return host.IndexOfValue (val);
+ }
+ }
+
+ public override void SetByIndex (int index, object value)
+ {
+ lock (host.SyncRoot) {
+ host.SetByIndex (index, value);
+ }
+ }
+
+ public override void TrimToSize()
+ {
+ lock (host.SyncRoot) {
+ host.TrimToSize();
+ }
+ }
+
+
+ } // SynchedSortedList
+
+ } // SortedList
+
} // System.Collections