Few corcompare fixes
[mono.git] / mcs / class / System / System.Collections.Generic / SortedList.cs
index 77fa2c3d2e547fff3f7f48170adf9a30c2377f3b..d91ce2ecf77c879b83b3a76b39a878d8da09e29d 100644 (file)
 // 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;
+using System.Diagnostics;
 
-namespace System.Collections.Generic {
-
+namespace System.Collections.Generic
+{
        /// <summary>
        ///  Represents a collection of associated keys and values
        ///  that are sorted by the keys and are accessible by key
@@ -47,6 +46,8 @@ namespace System.Collections.Generic {
        /// </summary>
        [Serializable]
        [ComVisible(false)]
+       [DebuggerDisplay ("Count={Count}")]
+       [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))]
        public class SortedList<TKey, TValue> : IDictionary<TKey, TValue>, 
                IDictionary,
                ICollection,
@@ -114,7 +115,7 @@ namespace System.Collections.Generic {
 
                // ICollection
 
-               public virtual int Count {
+               public int Count {
                        get {
                                return inUse;
                        }
@@ -146,7 +147,7 @@ namespace System.Collections.Generic {
                        }
                }
 
-               public virtual TValue this [TKey key] {
+               public TValue this [TKey key] {
                        get {
                                if (key == null)
                                        throw new ArgumentNullException("key");
@@ -268,9 +269,7 @@ namespace System.Collections.Generic {
                // Public instance methods.
                //
 
-               // IDictionary<TKey, TValue>
-
-               public virtual void Add (TKey key, TValue value)
+               public void Add (TKey key, TValue value)
                {
                        if (key == null)
                                throw new ArgumentNullException ("key");
@@ -295,7 +294,7 @@ namespace System.Collections.Generic {
                        }
                }
 
-               public virtual bool Remove (TKey key)
+               public bool Remove (TKey key)
                {
                        if (key == null)
                                throw new ArgumentNullException ("key");
@@ -311,7 +310,15 @@ namespace System.Collections.Generic {
 
                // ICollection<KeyValuePair<TKey, TValue>>
 
-               public virtual void Clear () 
+               void ICollection<KeyValuePair<TKey, TValue>>.Clear () 
+               {
+                       defaultCapacity = INITIAL_SIZE;
+                       this.table = new KeyValuePair<TKey, TValue> [defaultCapacity];
+                       inUse = 0;
+                       modificationCount++;
+               }
+
+               public void Clear () 
                {
                        defaultCapacity = INITIAL_SIZE;
                        this.table = new KeyValuePair<TKey, TValue> [defaultCapacity];
@@ -321,6 +328,9 @@ namespace System.Collections.Generic {
 
                void ICollection<KeyValuePair<TKey, TValue>>.CopyTo (KeyValuePair<TKey, TValue>[] array, int arrayIndex)
                {
+                       if (Count == 0)
+                               return;
+                       
                        if (null == array)
                                throw new ArgumentNullException();
 
@@ -415,6 +425,9 @@ namespace System.Collections.Generic {
 
                void ICollection.CopyTo (Array array, int arrayIndex)
                {
+                       if (Count == 0)
+                               return;
+                       
                        if (null == array)
                                throw new ArgumentNullException();
 
@@ -631,10 +644,10 @@ namespace System.Collections.Generic {
                        while (left <= right) {
                                int guess = (left + right) >> 1;
 
-                               int cmp = comparer.Compare (key, table[guess].Key);
+                               int cmp = comparer.Compare (table[guess].Key, key);
                                if (cmp == 0) return guess;
 
-                               if (cmp >  0) left = guess+1;
+                               if (cmp <  0) left = guess+1;
                                else right = guess-1;
                        }
 
@@ -794,6 +807,119 @@ namespace System.Collections.Generic {
                        }
                }
 
+               [Serializable]
+               struct KeyEnumerator : IEnumerator <TKey>, IDisposable {
+                       const int NOT_STARTED = -2;
+                       
+                       // this MUST be -1, because we depend on it in move next.
+                       // we just decr the size, so, 0 - 1 == FINISHED
+                       const int FINISHED = -1;
+                       
+                       SortedList <TKey, TValue> l;
+                       int idx;
+                       int ver;
+                       
+                       internal KeyEnumerator (SortedList<TKey, TValue> l)
+                       {
+                               this.l = l;
+                               idx = NOT_STARTED;
+                               ver = l.modificationCount;
+                       }
+                       
+                       public void Dispose ()
+                       {
+                               idx = NOT_STARTED;
+                       }
+                       
+                       public bool MoveNext ()
+                       {
+                               if (ver != l.modificationCount)
+                                       throw new InvalidOperationException ("Collection was modified after the enumerator was instantiated.");
+                               
+                               if (idx == NOT_STARTED)
+                                       idx = l.Count;
+                               
+                               return idx != FINISHED && -- idx != FINISHED;
+                       }
+                       
+                       public TKey Current {
+                               get {
+                                       if (idx < 0)
+                                               throw new InvalidOperationException ();
+                                       
+                                       return l.KeyAt (l.Count - 1 - idx);
+                               }
+                       }
+                       
+                       void IEnumerator.Reset ()
+                       {
+                               if (ver != l.modificationCount)
+                                       throw new InvalidOperationException ("Collection was modified after the enumerator was instantiated.");
+                               
+                               idx = NOT_STARTED;
+                       }
+                       
+                       object IEnumerator.Current {
+                               get { return Current; }
+                       }
+               }
+
+               [Serializable]
+               struct ValueEnumerator : IEnumerator <TValue>, IDisposable {
+                       const int NOT_STARTED = -2;
+                       
+                       // this MUST be -1, because we depend on it in move next.
+                       // we just decr the size, so, 0 - 1 == FINISHED
+                       const int FINISHED = -1;
+                       
+                       SortedList <TKey, TValue> l;
+                       int idx;
+                       int ver;
+                       
+                       internal ValueEnumerator (SortedList<TKey, TValue> l)
+                       {
+                               this.l = l;
+                               idx = NOT_STARTED;
+                               ver = l.modificationCount;
+                       }
+                       
+                       public void Dispose ()
+                       {
+                               idx = NOT_STARTED;
+                       }
+                       
+                       public bool MoveNext ()
+                       {
+                               if (ver != l.modificationCount)
+                                       throw new InvalidOperationException ("Collection was modified after the enumerator was instantiated.");
+                               
+                               if (idx == NOT_STARTED)
+                                       idx = l.Count;
+                               
+                               return idx != FINISHED && -- idx != FINISHED;
+                       }
+                       
+                       public TValue Current {
+                               get {
+                                       if (idx < 0)
+                                               throw new InvalidOperationException ();
+                                       
+                                       return l.ValueAt (l.Count - 1 - idx);
+                               }
+                       }
+                       
+                       void IEnumerator.Reset ()
+                       {
+                               if (ver != l.modificationCount)
+                                       throw new InvalidOperationException ("Collection was modified after the enumerator was instantiated.");
+                               
+                               idx = NOT_STARTED;
+                       }
+                       
+                       object IEnumerator.Current {
+                               get { return Current; }
+                       }
+               }
 
                private class ListKeys : IList<TKey>, ICollection, IEnumerable {
 
@@ -822,6 +948,8 @@ namespace System.Collections.Generic {
                        }
 
                        public virtual void CopyTo (TKey[] array, int arrayIndex) {
+                               if (host.Count == 0)
+                                       return;
                                if (array == null)
                                        throw new ArgumentNullException ("array");
                                if (arrayIndex < 0)
@@ -870,8 +998,8 @@ namespace System.Collections.Generic {
 
                        public virtual IEnumerator<TKey> GetEnumerator ()
                        {
-                               for (int i = 0; i < host.Count; ++i)
-                                       yield return host.KeyAt (i);
+                               /* We couldn't use yield as it does not support Reset () */
+                               return new KeyEnumerator (host);
                        }
 
                        //
@@ -945,6 +1073,8 @@ namespace System.Collections.Generic {
                        }
 
                        public virtual void CopyTo (TValue[] array, int arrayIndex) {
+                               if (host.Count == 0)
+                                       return;
                                if (array == null)
                                        throw new ArgumentNullException ("array");
                                if (arrayIndex < 0)
@@ -993,8 +1123,8 @@ namespace System.Collections.Generic {
 
                        public virtual IEnumerator<TValue> GetEnumerator ()
                        {
-                               for (int i = 0; i < host.Count; ++i)
-                                       yield return host.ValueAt (i);
+                               /* We couldn't use yield as it does not support Reset () */
+                               return new ValueEnumerator (host);
                        }
 
                        //
@@ -1044,5 +1174,3 @@ namespace System.Collections.Generic {
        } // SortedList
 
 } // System.Collections.Generic
-
-#endif