| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078 |
- //
- // System.Collections.Generic.SortedList.cs
- //
- // Author:
- // Sergey Chaban ([email protected])
- // Duncan Mak ([email protected])
- // Herve Poussineau ([email protected]
- // Zoltan Varga ([email protected])
- //
- //
- // Copyright (C) 2004 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.
- //
- #if NET_2_0
- using System;
- using System.Collections;
- using System.Globalization;
- using System.Runtime.InteropServices;
- namespace System.Collections.Generic {
- /// <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]
- [ComVisible(false)]
- public class SortedList<TKey, TValue> : IDictionary<TKey, TValue>,
- IDictionary,
- ICollection,
- ICollection<KeyValuePair<TKey, TValue>>,
- IEnumerable<KeyValuePair<TKey, TValue>>,
- IEnumerable {
- 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 KeyValuePair<TKey, TValue>[] table;
- private IComparer<TKey> comparer;
- private int defaultCapacity;
- //
- // Constructors
- //
- public SortedList ()
- : this (INITIAL_SIZE, null)
- {
- }
- public SortedList (int capacity)
- : this (capacity, null)
- {
- }
- public SortedList (int capacity, IComparer<TKey> comparer)
- {
- if (capacity < 0)
- throw new ArgumentOutOfRangeException ("initialCapacity");
- if (capacity == 0)
- defaultCapacity = 0;
- else
- defaultCapacity = INITIAL_SIZE;
- Init (comparer, capacity, true);
- }
- public SortedList (IComparer<TKey> comparer) : this (INITIAL_SIZE, comparer)
- {
- }
- public SortedList (IDictionary<TKey, TValue> dictionary) : this (dictionary, null)
- {
- }
- public SortedList (IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer)
- {
- if (dictionary == null)
- throw new ArgumentNullException ("dictionary");
- Init (comparer, dictionary.Count, true);
- foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
- Add (kvp.Key, kvp.Value);
- }
- //
- // Properties
- //
- // ICollection
- public virtual int Count {
- get {
- return inUse;
- }
- }
- bool ICollection.IsSynchronized {
- get {
- return false;
- }
- }
- Object ICollection.SyncRoot {
- get {
- return this;
- }
- }
- // IDictionary
- bool IDictionary.IsFixedSize {
- get {
- return false;
- }
- }
- bool IDictionary.IsReadOnly {
- get {
- return false;
- }
- }
- public virtual TValue this [TKey key] {
- get {
- if (key == null)
- throw new ArgumentNullException("key");
- int i = Find (key);
- if (i >= 0)
- return table [i].Value;
- else
- throw new KeyNotFoundException ();
- }
- set {
- if (key == null)
- throw new ArgumentNullException("key");
- PutImpl (key, value, true);
- }
- }
- object IDictionary.this [object key] {
- get {
- if (!(key is TKey))
- return null;
- else
- return this [(TKey)key];
- }
- set {
- this [ToKey (key)] = ToValue (value);
- }
- }
- public int Capacity {
- get {
- return table.Length;
- }
- set {
- int current = this.table.Length;
- if (inUse > value) {
- throw new ArgumentOutOfRangeException("capacity too small");
- }
- else if (value == 0) {
- // return to default size
- KeyValuePair<TKey, TValue> [] newTable = new KeyValuePair<TKey, TValue> [defaultCapacity];
- Array.Copy (table, newTable, inUse);
- this.table = newTable;
- }
- #if NET_1_0
- else if (current > defaultCapacity && value < current) {
- KeyValuePair<TKey, TValue> [] newTable = new KeyValuePair<TKey, TValue> [defaultCapacity];
- Array.Copy (table, newTable, inUse);
- this.table = newTable;
- }
- #endif
- else if (value > inUse) {
- KeyValuePair<TKey, TValue> [] newTable = new KeyValuePair<TKey, TValue> [value];
- Array.Copy (table, newTable, inUse);
- this.table = newTable;
- }
- else if (value > current) {
- KeyValuePair<TKey, TValue> [] newTable = new KeyValuePair<TKey, TValue> [value];
- Array.Copy (table, newTable, current);
- this.table = newTable;
- }
- }
- }
- public IList<TKey> Keys {
- get {
- return new ListKeys (this);
- }
- }
- public IList<TValue> Values {
- get {
- return new ListValues (this);
- }
- }
- ICollection IDictionary.Keys {
- get {
- return new ListKeys (this);
- }
- }
- ICollection IDictionary.Values {
- get {
- return new ListValues (this);
- }
- }
- ICollection<TKey> IDictionary<TKey, TValue>.Keys {
- get {
- return Keys;
- }
- }
- ICollection<TValue> IDictionary<TKey, TValue>.Values {
- get {
- return Values;
- }
- }
- public IComparer<TKey> Comparer {
- get {
- return comparer;
- }
- }
- bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
- get {
- return false;
- }
- }
- //
- // Public instance methods.
- //
- // IDictionary<TKey, TValue>
- void IDictionary<TKey,TValue>.Add (TKey key, TValue value)
- {
- if (key == null)
- throw new ArgumentNullException ("key");
- PutImpl (key, value, false);
- }
-
- public virtual void Add (TKey key, TValue value)
- {
- if (key == null)
- throw new ArgumentNullException ("key");
- PutImpl (key, value, false);
- }
- public bool ContainsKey (TKey key)
- {
- if (key == null)
- throw new ArgumentNullException ("key");
- return (Find (key) >= 0);
- }
- public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator ()
- {
- for (int i = 0; i < inUse; i ++) {
- KeyValuePair<TKey, TValue> current = this.table [i];
- yield return new KeyValuePair<TKey, TValue> (current.Key, current.Value);
- }
- }
- bool IDictionary<TKey,TValue>.Remove (TKey key)
- {
- if (key == null)
- throw new ArgumentNullException ("key");
- int i = IndexOfKey (key);
- if (i >= 0) {
- RemoveAt (i);
- return true;
- }
- else
- return false;
- }
- public virtual bool Remove (TKey key)
- {
- if (key == null)
- throw new ArgumentNullException ("key");
- int i = IndexOfKey (key);
- if (i >= 0) {
- RemoveAt (i);
- return true;
- }
- else
- return false;
- }
- // ICollection<KeyValuePair<TKey, TValue>>
- void ICollection<KeyValuePair<TKey, TValue>>.Clear ()
- {
- defaultCapacity = INITIAL_SIZE;
- this.table = new KeyValuePair<TKey, TValue> [defaultCapacity];
- inUse = 0;
- modificationCount++;
- }
- public virtual void Clear ()
- {
- defaultCapacity = INITIAL_SIZE;
- this.table = new KeyValuePair<TKey, TValue> [defaultCapacity];
- inUse = 0;
- modificationCount++;
- }
- void ICollection<KeyValuePair<TKey, TValue>>.CopyTo (KeyValuePair<TKey, TValue>[] array, int arrayIndex)
- {
- if (null == array)
- throw new ArgumentNullException();
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException();
-
- 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");
- int i = arrayIndex;
- foreach (KeyValuePair<TKey, TValue> pair in this)
- array [i++] = pair;
- }
- void ICollection<KeyValuePair<TKey, TValue>>.Add (KeyValuePair<TKey, TValue> keyValuePair) {
- Add (keyValuePair.Key, keyValuePair.Value);
- }
- bool ICollection<KeyValuePair<TKey, TValue>>.Contains (KeyValuePair<TKey, TValue> keyValuePair) {
- int i = Find (keyValuePair.Key);
- if (i >= 0)
- return Comparer<KeyValuePair<TKey, TValue>>.Default.Compare (table [i], keyValuePair) == 0;
- else
- return false;
- }
- bool ICollection<KeyValuePair<TKey, TValue>>.Remove (KeyValuePair<TKey, TValue> keyValuePair) {
- int i = Find (keyValuePair.Key);
- if (i >= 0 && (Comparer<KeyValuePair<TKey, TValue>>.Default.Compare (table [i], keyValuePair) == 0)) {
- RemoveAt (i);
- return true;
- }
- else
- return false;
- }
- // IEnumerable<KeyValuePair<TKey, TValue>>
- IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator ()
- {
- for (int i = 0; i < inUse; i ++) {
- KeyValuePair<TKey, TValue> current = this.table [i];
- yield return new KeyValuePair<TKey, TValue> (current.Key, current.Value);
- }
- }
- // IEnumerable
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return GetEnumerator ();
- }
- // IDictionary
- void IDictionary.Add (object key, object value)
- {
- PutImpl (ToKey (key), ToValue (value), false);
- }
- bool IDictionary.Contains (object key)
- {
- if (null == key)
- throw new ArgumentNullException();
- if (!(key is TKey))
- return false;
- return (Find ((TKey)key) >= 0);
- }
- IDictionaryEnumerator IDictionary.GetEnumerator ()
- {
- return new Enumerator (this, EnumeratorMode.ENTRY_MODE);
- }
- void IDictionary.Remove (object key)
- {
- if (null == key)
- throw new ArgumentNullException ("key");
- if (!(key is TKey))
- return;
- int i = IndexOfKey ((TKey)key);
- if (i >= 0) RemoveAt (i);
- }
- // ICollection
- void ICollection.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");
- IEnumerator<KeyValuePair<TKey,TValue>> it = GetEnumerator ();
- int i = arrayIndex;
- while (it.MoveNext ()) {
- array.SetValue (it.Current, i++);
- }
- }
- //
- // SortedList<TKey, TValue>
- //
- public void RemoveAt (int index)
- {
- KeyValuePair<TKey, TValue> [] 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] = default (KeyValuePair <TKey, TValue>);
- }
- --inUse;
- ++modificationCount;
- } else {
- throw new ArgumentOutOfRangeException("index out of range");
- }
- }
- public int IndexOfKey (TKey key)
- {
- if (key == null)
- throw new ArgumentNullException ("key");
- int indx = 0;
- try {
- indx = Find (key);
- } catch (Exception) {
- throw new InvalidOperationException();
- }
- return (indx | (indx >> 31));
- }
- public int IndexOfValue (TValue value)
- {
- if (inUse == 0)
- return -1;
- for (int i = 0; i < inUse; i ++) {
- KeyValuePair<TKey, TValue> current = this.table [i];
- if (Equals (value, current.Value))
- return i;
- }
- return -1;
- }
- public bool ContainsValue (TValue value)
- {
- return IndexOfValue (value) >= 0;
- }
- public void TrimExcess ()
- {
- if (inUse < table.Length * 0.9)
- Capacity = inUse;
- }
- public bool TryGetValue (TKey key, out TValue value)
- {
- if (key == null)
- throw new ArgumentNullException("key");
- int i = Find (key);
- if (i >= 0) {
- value = table [i].Value;
- return true;
- }
- else {
- value = default (TValue);
- return false;
- }
- }
- //
- // Private methods
- //
- private void EnsureCapacity (int n, int free)
- {
- KeyValuePair<TKey, TValue> [] table = this.table;
- KeyValuePair<TKey, TValue> [] newTable = null;
- int cap = Capacity;
- bool gap = (free >=0 && free < Count);
- if (n > cap) {
- newTable = new KeyValuePair<TKey, TValue> [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 (TKey key, TValue value, bool overwrite)
- {
- if (key == null)
- throw new ArgumentNullException ("null key");
- KeyValuePair<TKey, TValue> [] table = this.table;
- int freeIndx = -1;
- try {
- freeIndx = Find (key);
- } catch (Exception) {
- throw new InvalidOperationException();
- }
- if (freeIndx >= 0) {
- if (!overwrite)
- throw new ArgumentException("element already exists");
- table [freeIndx] = new KeyValuePair <TKey, TValue> (key, 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] = new KeyValuePair <TKey, TValue> (key, value);
- ++inUse;
- ++modificationCount;
- }
- private void Init (IComparer<TKey> comparer, int capacity, bool forceSize)
- {
- if (comparer == null)
- comparer = Comparer<TKey>.Default;
- this.comparer = comparer;
- if (!forceSize && (capacity < defaultCapacity))
- capacity = defaultCapacity;
- this.table = new KeyValuePair<TKey, TValue> [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 (TKey key)
- {
- KeyValuePair<TKey, TValue> [] table = this.table;
- int len = Count;
- if (len == 0) return ~0;
- 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;
- }
- private TKey ToKey (object key) {
- if (key == null)
- throw new ArgumentNullException ("key");
- if (!(key is TKey))
- throw new ArgumentException ("The value \"" + key + "\" isn't of type \"" + typeof (TKey) + "\" and can't be used in this generic collection.", "key");
- return (TKey)key;
- }
- private TValue ToValue (object value) {
- if (!(value is TValue))
- throw new ArgumentException ("The value \"" + value + "\" isn't of type \"" + typeof (TValue) + "\" and can't be used in this generic collection.", "value");
- return (TValue)value;
- }
- internal TKey KeyAt (int index) {
- if (index >= 0 && index < Count)
- return table [index].Key;
- else
- throw new ArgumentOutOfRangeException("Index out of range");
- }
- internal TValue ValueAt (int index) {
- if (index >= 0 && index < Count)
- return table [index].Value;
- else
- throw new ArgumentOutOfRangeException("Index out of range");
- }
- //
- // Inner classes
- //
- private sealed class Enumerator : ICloneable, IDictionaryEnumerator, IEnumerator {
- private SortedList<TKey, TValue>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<TKey, TValue>host, EnumeratorMode mode)
- {
- this.host = host;
- stamp = host.modificationCount;
- size = host.Count;
- this.mode = mode;
- Reset ();
- }
- public Enumerator (SortedList<TKey, TValue>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);
- KeyValuePair<TKey, TValue> [] table = host.table;
- if (++pos < size) {
- KeyValuePair<TKey, TValue> 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
- public object Clone ()
- {
- Enumerator e = new Enumerator (host, mode);
- e.stamp = stamp;
- e.pos = pos;
- e.size = size;
- e.currentKey = currentKey;
- e.currentValue = currentValue;
- e.invalid = invalid;
- return e;
- }
- }
- private class ListKeys : IList<TKey>, ICollection, IEnumerable {
- private SortedList<TKey, TValue> host;
- public ListKeys (SortedList<TKey, TValue> host)
- {
- if (host == null)
- throw new ArgumentNullException ();
- this.host = host;
- }
- // ICollection<TKey>
- public virtual void Add (TKey item) {
- throw new NotSupportedException();
- }
- public virtual bool Remove (TKey key) {
- throw new NotSupportedException ();
- }
- public virtual void Clear () {
- throw new NotSupportedException();
- }
- public virtual void CopyTo (TKey[] array, int arrayIndex) {
- if (array == null)
- throw new ArgumentNullException ("array");
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException();
- if (arrayIndex >= array.Length)
- throw new ArgumentOutOfRangeException ("arrayIndex is greater than or equal to array.Length");
- if (Count > (array.Length - arrayIndex))
- throw new ArgumentOutOfRangeException("Not enough space in array from arrayIndex to end of array");
- int j = arrayIndex;
- for (int i = 0; i < Count; ++i)
- array [j ++] = host.KeyAt (i);
- }
- public virtual bool Contains (TKey item) {
- return host.IndexOfKey (item) > -1;
- }
- //
- // IList<TKey>
- //
- public virtual int IndexOf (TKey item) {
- return host.IndexOfKey (item);
- }
- public virtual void Insert (int index, TKey item) {
- throw new NotSupportedException ();
- }
- public virtual void RemoveAt (int index) {
- throw new NotSupportedException ();
- }
- public virtual TKey this [int index] {
- get {
- return host.KeyAt (index);
- }
- set {
- throw new NotSupportedException("attempt to modify a key");
- }
- }
- //
- // IEnumerable<TKey>
- //
- public virtual IEnumerator<TKey> GetEnumerator ()
- {
- for (int i = 0; i < host.Count; ++i)
- yield return host.KeyAt (i);
- }
- //
- // ICollection
- //
- public virtual int Count {
- get {
- return host.Count;
- }
- }
- public virtual bool IsSynchronized {
- get {
- return ((ICollection)host).IsSynchronized;
- }
- }
- public virtual bool IsReadOnly {
- get {
- return true;
- }
- }
- public virtual Object SyncRoot {
- get {
- return ((ICollection)host).SyncRoot;
- }
- }
- public virtual void CopyTo (Array array, int arrayIndex)
- {
- host.CopyToArray (array, arrayIndex, EnumeratorMode.KEY_MODE);
- }
- //
- // IEnumerable
- //
- IEnumerator IEnumerable.GetEnumerator ()
- {
- for (int i = 0; i < host.Count; ++i)
- yield return host.KeyAt (i);
- }
- }
- private class ListValues : IList<TValue>, ICollection, IEnumerable {
- private SortedList<TKey, TValue>host;
- public ListValues (SortedList<TKey, TValue>host)
- {
- if (host == null)
- throw new ArgumentNullException ();
- this.host = host;
- }
- // ICollection<TValue>
- public virtual void Add (TValue item) {
- throw new NotSupportedException();
- }
- public virtual bool Remove (TValue value) {
- throw new NotSupportedException ();
- }
- public virtual void Clear () {
- throw new NotSupportedException();
- }
- public virtual void CopyTo (TValue[] array, int arrayIndex) {
- if (array == null)
- throw new ArgumentNullException ("array");
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException();
- if (arrayIndex >= array.Length)
- throw new ArgumentOutOfRangeException ("arrayIndex is greater than or equal to array.Length");
- if (Count > (array.Length - arrayIndex))
- throw new ArgumentOutOfRangeException("Not enough space in array from arrayIndex to end of array");
- int j = arrayIndex;
- for (int i = 0; i < Count; ++i)
- array [j ++] = host.ValueAt (i);
- }
- public virtual bool Contains (TValue item) {
- return host.IndexOfValue (item) > -1;
- }
- //
- // IList<TValue>
- //
- public virtual int IndexOf (TValue item) {
- return host.IndexOfValue (item);
- }
- public virtual void Insert (int index, TValue item) {
- throw new NotSupportedException ();
- }
- public virtual void RemoveAt (int index) {
- throw new NotSupportedException ();
- }
- public virtual TValue this [int index] {
- get {
- return host.ValueAt (index);
- }
- set {
- throw new NotSupportedException("attempt to modify a key");
- }
- }
- //
- // IEnumerable<TValue>
- //
- public virtual IEnumerator<TValue> GetEnumerator ()
- {
- for (int i = 0; i < host.Count; ++i)
- yield return host.ValueAt (i);
- }
- //
- // ICollection
- //
- public virtual int Count {
- get {
- return host.Count;
- }
- }
- public virtual bool IsSynchronized {
- get {
- return ((ICollection)host).IsSynchronized;
- }
- }
- public virtual bool IsReadOnly {
- get {
- return true;
- }
- }
- public virtual Object SyncRoot {
- get {
- return ((ICollection)host).SyncRoot;
- }
- }
- public virtual void CopyTo (Array array, int arrayIndex)
- {
- host.CopyToArray (array, arrayIndex, EnumeratorMode.VALUE_MODE);
- }
- //
- // IEnumerable
- //
- IEnumerator IEnumerable.GetEnumerator ()
- {
- for (int i = 0; i < host.Count; ++i)
- yield return host.ValueAt (i);
- }
- }
- } // SortedList
- } // System.Collections.Generic
- #endif
|