2006-04-05 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Wed, 5 Apr 2006 07:36:29 +0000 (07:36 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Wed, 5 Apr 2006 07:36:29 +0000 (07:36 -0000)
* System.dll.sources : added SortedDictionary.cs.
* System_test.dll.sources : added SortedDictionaryTest.cs.

* SortedDictionary.cs : new file. The original code is mostly
  from Kazuki Oikawa.

* SortedDictionaryTest.cs : new test.

svn path=/trunk/mcs/; revision=59052

mcs/class/System/ChangeLog
mcs/class/System/System.Collections.Generic/ChangeLog
mcs/class/System/System.Collections.Generic/SortedDictionary.cs [new file with mode: 0644]
mcs/class/System/System.dll.sources
mcs/class/System/System_test.dll.sources
mcs/class/System/Test/System.Collections.Generic/ChangeLog
mcs/class/System/Test/System.Collections.Generic/SortedDictionaryTest.cs [new file with mode: 0644]

index f0b3d484d428170d93e72067954324df7e999e66..455e8cae5a67c18061237617bc3a815e07ff601e 100644 (file)
@@ -1,3 +1,8 @@
+2006-04-05  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * System.dll.sources : added SortedDictionary.cs.
+       * System_test.dll.sources : added SortedDictionaryTest.cs.
+
 2006-04-04  Atsushi Enomoto  <atsushi@ximian.com>
 
        * System.dll.sources: added DataReceivedEventArgs.cs and
index 7f6dcba2605b88d43c546861e20bbb140f4d1311..8887fe9baebe5ff37d8ab82cba17ef14ec572340 100644 (file)
@@ -1,3 +1,8 @@
+2006-04-05  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * SortedDictionary.cs : new file. The original code is mostly
+         from Kazuki Oikawa.
+
 2006-03-11  Miguel de Icaza  <miguel@novell.com>
 
        * Queue.cs: Flag as serializable.
diff --git a/mcs/class/System/System.Collections.Generic/SortedDictionary.cs b/mcs/class/System/System.Collections.Generic/SortedDictionary.cs
new file mode 100644 (file)
index 0000000..7673ffc
--- /dev/null
@@ -0,0 +1,786 @@
+//
+// System.Collections.Generic.SortedDictionary
+//
+// Authors:
+//    Kazuki Oikawa (kazuki@panicode.com)
+//    Atsushi Enomoto (atsushi@ximian.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;
+
+namespace System.Collections.Generic
+{
+       [Serializable]
+       public class SortedDictionary<TKey,TValue> : IDictionary<TKey,TValue>, ICollection<KeyValuePair<TKey,TValue>>, IEnumerable<KeyValuePair<TKey,TValue>>, IDictionary, ICollection, IEnumerable
+       {
+               TKey [] _keys;
+               TValue [] _values;
+               IComparer<TKey> _comparer;
+               int _size;
+               int _version = 0;
+               const int DefaultCapacitySize = 4;
+
+               KeyCollection _keyList;
+               ValueCollection _valueList;
+
+               #region Constructor
+               public SortedDictionary () : this (0, null)
+               {
+               }
+
+               public SortedDictionary (IComparer<TKey> comparer) : this (0, comparer)
+               {
+               }
+
+               public SortedDictionary (IDictionary<TKey,TValue> dic) : this (dic, null)
+               {
+               }
+
+               // it disappeared in 2.0 RTM
+               SortedDictionary (int capacity) : this (capacity, null)
+               {
+
+               }
+
+               public SortedDictionary (IDictionary<TKey,TValue> dic, IComparer<TKey> comparer) : this (dic == null ? 0 : dic.Count, comparer)
+               {
+                       if (dic == null)
+                               throw new ArgumentNullException ();
+
+                       dic.Keys.CopyTo (_keys, 0);
+                       dic.Values.CopyTo (_values, 0);
+                       Array.Sort<TKey,TValue> (_keys, _values);
+                       _size = dic.Count;
+               }
+
+               // it disappeared in 2.0 RTM
+               SortedDictionary (int capacity, IComparer<TKey> comparer)
+               {
+                       if (capacity < 0)
+                               throw new ArgumentOutOfRangeException ();
+
+                       _keys = new TKey [capacity];
+                       _values = new TValue [capacity];
+                       _size = 0;
+
+                       if (comparer == null)
+                               _comparer = Comparer<TKey>.Default;
+                       else
+                               _comparer = comparer;
+               }
+               #endregion
+
+               #region PublicProperty
+
+               public IComparer<TKey> Comparer {
+                       get { return _comparer; }
+               }
+
+               // It disappeared in 2.0 RTM.
+               int Capacity {
+                       get { return _keys.Length; }
+                       set {
+                               if (value < _size)
+                                       throw new ArgumentOutOfRangeException ();
+                               
+                               Array.Resize<TKey> (ref _keys, value);
+                               Array.Resize<TValue> (ref _values, value);
+                       }
+               }
+
+               public int Count {
+                       get { return _size; }
+               }
+
+               public TValue this [TKey key] {
+                       get {
+                               int index = IndexOfKey (key);
+                               if (index >= 0)
+                                       return _values [index];
+                               
+                               throw new KeyNotFoundException ();
+                       }
+                       set {
+                               if (key == null)
+                                       throw new ArgumentNullException ();
+                               
+                               int index = IndexOfKey (key);
+                               if (index < 0)
+                                       Add (key, value);
+                               else
+                                       _values [index] = value;
+                       }
+               }
+
+               public KeyCollection Keys {
+                       get { return GetKeyCollection (); }
+               }
+
+               public ValueCollection Values {
+                       get { return GetValueCollection (); }
+               }
+               #endregion
+
+               #region PublicMethod
+
+               public void Add (TKey key, TValue value)
+               {
+                       if (key == null) 
+                               throw new ArgumentNullException ();
+                       
+                       int index = Array.BinarySearch<TKey> (_keys, 0, _size, key, _comparer);
+                       if (index >= 0)
+                               throw new ArgumentException ();
+
+                       index = ~index;
+
+                       if (_size == _keys.Length)
+                               Capacity += Capacity > 0 ? Capacity : DefaultCapacitySize;
+
+                       if (index < _size) {
+                               Array.Copy (_keys, index, _keys, index + 1, _size - index);
+                               Array.Copy (_values, index, _values, index + 1, _size - index);
+                       }
+
+                       _keys [index] = key;
+                       _values [index] = value;
+                       _size++;
+                       _version++;
+               }
+
+               public void Clear ()
+               {
+                       Array.Clear (_keys, 0, _size);
+                       Array.Clear (_values, 0, _size);
+                       _size = 0;
+                       _version++;
+               }
+
+               public bool ContainsKey (TKey key)
+               {
+                       return IndexOfKey (key) >= 0;
+               }
+
+               public bool ContainsValue (TValue value)
+               {
+                       return IndexOfValue (value) >= 0;
+               }
+
+               public void CopyTo (KeyValuePair<TKey,TValue>[] array, int arrayIndex)
+               {
+                       if (array == null)
+                               throw new ArgumentNullException ();
+                       if (arrayIndex < 0 || array.Length <= arrayIndex)
+                               throw new ArgumentOutOfRangeException ();
+                       if (array.Length - arrayIndex < _size)
+                               throw new ArgumentException ();
+
+                       for (int i = 0; i < _size; i ++) {
+                               array [arrayIndex + i] = new KeyValuePair<TKey,TValue> (_keys [i], _values [i]);
+                       }
+               }
+               
+               public Enumerator GetEnumerator ()
+               {
+                       return new Enumerator (this);
+               }
+
+               int IndexOfKey (TKey key)
+               {
+                       if (key == null)
+                               throw new ArgumentNullException ();
+
+                       return Array.BinarySearch<TKey> (_keys, 0, _size, key, _comparer);
+               }
+
+               int IndexOfValue (TValue value)
+               {
+                       return Array.IndexOf<TValue> (_values, value, 0, _size);
+               }
+
+               public bool Remove (TKey key)
+               {
+                       int index = IndexOfKey (key);
+                       if (index >= 0) {
+                               RemoveAt (index);
+                               return true;
+                       }
+                       return false;
+               }
+
+               void RemoveAt (int index)
+               {
+                       if (index < 0 || _size <= index)
+                               throw new ArgumentOutOfRangeException ();
+
+                       _size--;
+                       if (index < _size) {
+                               Array.Copy (_keys, index + 1, _keys, index, _size - index);
+                               Array.Copy (_values, index + 1, _values, index, _size - index);
+                       }
+
+                       _keys[_size] = default (TKey) ;
+                       _values[_size] = default (TValue) ;
+                       _version++;
+               }
+
+               public bool TryGetValue (TKey key, out TValue value)
+               {
+                       int index = IndexOfKey (key);
+                       if (index >= 0) {
+                               value = _values [index];
+                               return true;
+                       }
+
+                       value = default (TValue) ;
+                       return false;                   
+               }
+
+               #endregion
+
+               #region PrivateMethod
+               private KeyCollection GetKeyCollection ()
+               {
+                       if (_keyList == null)
+                               _keyList = new KeyCollection (this);
+                       return _keyList;
+               }
+               private ValueCollection GetValueCollection ()
+               {
+                       if (_valueList == null)
+                               _valueList = new ValueCollection (this);
+                       return _valueList;
+               }
+
+               TKey ToKey (object key)
+               {
+                       if (key == null)
+                               throw new ArgumentNullException ("key");
+                       if (!(key is TKey))
+                               throw new ArgumentException (String.Format ("Key \"{0}\" cannot be converted to the key type {1}.", key, typeof (TKey)));
+                       return (TKey) key;
+               }
+
+               TValue ToValue (object value)
+               {
+                       if (!(value is TValue) && (value != null || typeof (TValue).IsValueType))
+                               throw new ArgumentException (String.Format ("Value \"{0}\" cannot be converted to the value type {1}.", value, typeof (TValue)));
+                       return (TValue) value;
+               }
+               #endregion
+
+               #region IDictionary<TKey,TValue> Member
+
+               ICollection<TKey> IDictionary<TKey,TValue>.Keys {
+                       get { return GetKeyCollection (); }
+               }
+
+               ICollection<TValue> IDictionary<TKey,TValue>.Values {
+                       get { return GetValueCollection (); }
+               }
+
+               #endregion
+
+               #region ICollection<KeyValuePair<TKey,TValue>> Member
+
+               void ICollection<KeyValuePair<TKey,TValue>>.Add (KeyValuePair<TKey,TValue> item)
+               {
+                       Add (item.Key, item.Value);
+               }
+
+               bool ICollection<KeyValuePair<TKey,TValue>>.Contains (KeyValuePair<TKey,TValue> item)
+               {
+                       int index = IndexOfKey (item.Key);
+                       return index >= 0 && Comparer<TValue>.Default.Compare (_values [index], item.Value) == 0;
+               }
+
+               bool ICollection<KeyValuePair<TKey,TValue>>.IsReadOnly {
+                       get { return false; }
+               }
+
+               bool ICollection<KeyValuePair<TKey,TValue>>.Remove (KeyValuePair<TKey,TValue> item)
+               {
+                       int index = IndexOfKey (item.Key);
+                       if (index >= 0 && Comparer<TValue>.Default.Compare (_values [index], item.Value) == 0) {
+                               RemoveAt (index);
+                               return true;
+                       }
+                       return false;
+               }
+
+               #endregion
+
+               #region IDictionary Member
+
+               void IDictionary.Add (object key, object value)
+               {
+                       Add (ToKey (key), ToValue (value));
+               }
+
+               bool IDictionary.Contains (object key)
+               {
+                       return ContainsKey (ToKey (key));
+               }
+
+               IDictionaryEnumerator IDictionary.GetEnumerator ()
+               {
+                       return new Enumerator (this);
+               }
+
+               bool IDictionary.IsFixedSize {
+                       get { return false; }
+               }
+
+               bool IDictionary.IsReadOnly {
+                       get { return false; }
+               }
+
+               ICollection IDictionary.Keys  {
+                       get { return GetKeyCollection (); }
+               }
+
+               void IDictionary.Remove (object key)
+               {
+                       Remove (ToKey (key));
+               }
+               ICollection IDictionary.Values {
+                       get { return GetValueCollection (); }
+               }
+
+               object IDictionary.this [object key] {
+                       get {
+                               return this [ToKey (key)];
+                       }
+                       set {
+                               if (!(value is TValue))
+                                       throw new ArgumentException ();
+
+                               this [ToKey (key)] = ToValue (value);
+                       }
+               }
+
+               #endregion
+
+               #region ICollection Member
+
+               void ICollection.CopyTo (Array array, int index)
+               {
+                       if (array == null)
+                               throw new ArgumentNullException ();
+                       if (index < 0 || array.Length <= index)
+                               throw new ArgumentOutOfRangeException ();
+                       if (array.Length - index < _size)
+                               throw new ArgumentException ();
+
+                       for (int i = 0; i < _size; i ++) {
+                               array.SetValue (new KeyValuePair<TKey,TValue> (_keys [i], _values [i]), i);
+                       }
+               }
+
+               bool ICollection.IsSynchronized {
+                       get { return false; }
+               }
+
+               // TODO:Is this correct? If this is wrong,please fix.
+               object ICollection.SyncRoot {
+                       get { return this; }
+               }
+
+               #endregion
+
+               #region IEnumerable Member
+
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       return new Enumerator (this);
+               }
+
+               #endregion
+
+               #region IEnumerable<TKey> Member
+
+               IEnumerator<KeyValuePair<TKey,TValue>> IEnumerable<KeyValuePair<TKey,TValue>>.GetEnumerator ()
+               {
+                       return new Enumerator (this);
+               }
+
+               #endregion
+
+               [Serializable]
+               public sealed class ValueCollection : ICollection<TValue>,
+                       IEnumerable<TValue>, ICollection, IEnumerable
+               {
+                       SortedDictionary<TKey,TValue> _dic;
+
+                       public ValueCollection (SortedDictionary<TKey,TValue> dic)
+                       {
+                               _dic = dic;
+                       }
+
+                       void ICollection<TValue>.Add (TValue item)
+                       {
+                               throw new NotSupportedException ();
+                       }
+
+                       void ICollection<TValue>.Clear ()
+                       {
+                               throw new NotSupportedException ();
+                       }
+
+                       bool ICollection<TValue>.Contains (TValue item)
+                       {
+                               return _dic.ContainsValue (item);
+                       }
+
+                       public void CopyTo (TValue [] array, int arrayIndex)
+                       {
+                               if (array == null)
+                                       throw new ArgumentNullException ();
+                               if (arrayIndex < 0 || array.Length <= arrayIndex)
+                                       throw new ArgumentOutOfRangeException ();
+                               if (array.Length - arrayIndex < _dic._size)
+                                       throw new ArgumentException ();
+                               Array.Copy (_dic._values, 0, array, arrayIndex, _dic._size);
+                       }
+
+                       public int Count {
+                               get { return _dic._size; }
+                       }
+
+                       bool ICollection<TValue>.IsReadOnly {
+                               get { return true; }
+                       }
+
+                       bool ICollection<TValue>.Remove (TValue item)
+                       {
+                               throw new NotSupportedException ();
+                       }
+
+                       IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator ()
+                       {
+                               return GetEnumerator ();
+                       }
+
+                       public Enumerator GetEnumerator ()
+                       {
+                               return new Enumerator (_dic);
+                       }
+               
+                       void ICollection.CopyTo(Array array, int index)
+                       {
+                               if (array == null)
+                                       throw new ArgumentNullException ();
+                               if (index < 0 || array.Length <= index)
+                                       throw new ArgumentOutOfRangeException ();
+                               if (array.Length - index < _dic._size)
+                                       throw new ArgumentException ();
+                               Array.Copy (_dic._values, 0, array, index, _dic._size);
+                       }
+
+                       bool ICollection.IsSynchronized {
+                               get { return false; }
+                       }
+
+                       object ICollection.SyncRoot {
+                               get { return _dic; }
+                       }
+
+                       IEnumerator IEnumerable.GetEnumerator ()
+                       {
+                               return new Enumerator (_dic);
+                       }
+
+                       public struct Enumerator : IEnumerator<TValue>,IEnumerator, IDisposable
+                       {
+                               SortedDictionary<TKey,TValue> _dic;
+                               int _version;
+                               int _index;
+                               int _count;
+
+                               internal Enumerator (SortedDictionary<TKey,TValue> dic)
+                               {
+                                       _dic = dic;
+                                       _version = dic._version;
+                                       _index = -1;
+                                       _count = dic._size;
+                               }
+
+                               public TValue Current {
+                                       get {
+                                               if (_count <= _index)
+                                                       throw new InvalidOperationException ();
+                                               return _dic._values [_index];
+                                       }
+                               }
+
+                               public bool MoveNext ()
+                               {
+                                       if (_version != _dic._version)
+                                               throw new InvalidOperationException ();
+
+                                       if (_index + 1 < _count) {
+                                               _index ++;
+                                               return true;
+                                       }
+
+                                       return false;
+                               }
+
+                               public void Dispose ()
+                               {
+                                       _dic = null;
+                               }
+
+                               object IEnumerator.Current {
+                                       get { return Current; }
+                               }
+
+                               void IEnumerator.Reset ()
+                               {
+                                       if (_version != _dic._version)
+                                               throw new InvalidOperationException ();
+                                       _index = -1;
+                               }
+                       }
+               }
+
+               [Serializable]
+               public sealed class KeyCollection : ICollection<TKey>,
+                       IEnumerable<TKey>, ICollection, IEnumerable
+               {
+                       SortedDictionary<TKey,TValue> _dic;
+
+                       public KeyCollection (SortedDictionary<TKey,TValue> dic)
+                       {
+                               _dic = dic;
+                       }
+
+                       void ICollection<TKey>.Add (TKey item)
+                       {
+                               throw new NotSupportedException ();
+                       }
+
+                       void ICollection<TKey>.Clear ()
+                       {
+                               throw new NotSupportedException ();
+                       }
+
+                       bool ICollection<TKey>.Contains (TKey item)
+                       {
+                               return _dic.ContainsKey (item);
+                       }
+
+                       IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator ()
+                       {
+                               return GetEnumerator ();
+                       }
+
+                       public void CopyTo (TKey [] array, int arrayIndex)
+                       {
+                               Array.Copy (_dic._keys, 0, array, arrayIndex, _dic._size);
+                       }
+
+                       public int Count {
+                               get { return _dic._size; }
+                       }
+
+                       bool ICollection<TKey>.IsReadOnly {
+                               get { return true; }
+                       }
+
+                       bool ICollection<TKey>.Remove (TKey item)
+                       {
+                               throw new NotSupportedException ();
+                       }
+
+                       public Enumerator GetEnumerator ()
+                       {
+                               return new Enumerator (_dic);
+                       }
+
+                       void ICollection.CopyTo (Array array, int index)
+                       {
+                               if (array == null)
+                                       throw new ArgumentNullException ();
+                               if (index < 0 || array.Length <= index)
+                                       throw new ArgumentOutOfRangeException ();
+                               if (array.Length - index < _dic._size)
+                                       throw new ArgumentException ();
+                               Array.Copy (_dic._keys, 0, array, index, _dic._size);
+                       }
+
+                       bool ICollection.IsSynchronized {
+                               get { return false; }
+                       }
+
+                       object ICollection.SyncRoot {
+                               get { return _dic; }
+                       }
+
+                       IEnumerator IEnumerable.GetEnumerator ()
+                       {
+                               return new Enumerator (_dic);
+                       }
+
+                       public struct Enumerator : IEnumerator<TKey>, IEnumerator, IDisposable
+                       {
+                               SortedDictionary<TKey,TValue> _dic;
+                               int _version;
+                               int _index;
+                               int _count;
+
+                               internal Enumerator (SortedDictionary<TKey,TValue> dic)
+                               {
+                                       _dic = dic;
+                                       _version = dic._version;
+                                       _index = -1;
+                                       _count = dic._size;
+                               }
+
+                               public TKey Current {
+                                       get {
+                                               if (_count <= _index)
+                                                       throw new InvalidOperationException ();
+                                               return _dic._keys [_index];
+                                       }
+                               }
+
+                               public bool MoveNext ()
+                               {
+                                       if (_version != _dic._version)
+                                               throw new InvalidOperationException ();
+
+                                       if (_index + 1 < _count) {
+                                               _index ++;
+                                               return true;
+                                       }
+
+                                       return false;
+                               }
+
+                               public void Dispose ()
+                               {
+                                       _dic = null;
+                               }
+
+                               object IEnumerator.Current {
+                                       get { return Current; }
+                               }
+
+                               void IEnumerator.Reset ()
+                               {
+                                       if (_version != _dic._version)
+                                               throw new InvalidOperationException ();
+                                       _index = -1;
+                               }
+                       }
+
+               }
+
+               public struct Enumerator : IEnumerator<KeyValuePair<TKey,TValue>>, IDisposable , IDictionaryEnumerator, IEnumerator
+               {
+                       SortedDictionary<TKey,TValue> _dic;
+                       int _version;
+                       int _index;
+                       int _count;
+
+                       internal Enumerator (SortedDictionary<TKey,TValue> dic)
+                       {
+                               _dic = dic;
+                               _version = dic._version;
+                               _index = -1;
+                               _count = dic._size;
+                       }
+
+                       public KeyValuePair<TKey,TValue> Current {
+                               get {
+                                       if (_count <= _index)
+                                               throw new InvalidOperationException ();
+                                       return new KeyValuePair<TKey,TValue> (_dic._keys [_index], _dic._values [_index]);
+                               }
+                       }
+
+                       public bool MoveNext ()
+                       {
+                               if (_version != _dic._version)
+                                       throw new InvalidOperationException ();
+
+                               if (_index + 1 < _count) {
+                                       _index ++;
+                                       return true;
+                               }
+
+                               return false;
+                       }
+
+                       public void Dispose ()
+                       {
+                               _dic = null;
+                       }
+
+                       DictionaryEntry IDictionaryEnumerator.Entry {
+                               get {
+                                       if (_count <= _index)
+                                               throw new InvalidOperationException ();
+                                       return new DictionaryEntry (_dic._keys [_index], _dic._values [_index]);
+                               }
+                       }
+
+                       object IDictionaryEnumerator.Key {
+                               get {
+                                       if (_count <= _index)
+                                               throw new InvalidOperationException ();
+                                       return _dic._keys [_index];
+                               }
+                       }
+
+                       object IDictionaryEnumerator.Value {
+                               get {
+                                       if (_count <= _index)
+                                               throw new InvalidOperationException ();
+                                       return _dic._values [_index];
+                               }
+                       }
+
+                       object IEnumerator.Current {
+                               get {
+                                       if (_count <= _index)
+                                               throw new InvalidOperationException ();
+                                       return new DictionaryEntry (_dic._keys [_index], _dic._values [_index]);
+                               }
+                       }
+
+                       void IEnumerator.Reset ()
+                       {
+                               if (_version != _dic._version)
+                                       throw new InvalidOperationException ();
+
+                               _index = -1;
+                       }
+               }
+       }
+}
+#endif
index bb988c7446c4a5d9729eb8991288eefcfd17a154..12dc5acef676c3c28fb258762e28c597726e0eb6 100644 (file)
@@ -137,6 +137,7 @@ System.CodeDom/MemberAttributes.cs
 System.Collections.Generic/LinkedList.cs
 System.Collections.Generic/LinkedListNode.cs
 System.Collections.Generic/Queue.cs
+System.Collections.Generic/SortedDictionary.cs
 System.Collections.Generic/SortedList.cs
 System.Collections.Generic/Stack.cs
 System.Collections.Specialized/BitVector32.cs
index 51d72ddac5bc95eadc496f9f142d12e65e7e41f0..9e23f7375b94ce0e0a99f16c3c1afaf48ca5c038 100644 (file)
@@ -93,6 +93,7 @@ System.CodeDom.Compiler/TempFileCollectionTest.cs
 System.Collections.Generic/QueueTest.cs
 System.Collections.Generic/StackTest.cs
 System.Collections.Generic/LinkedListTest.cs
+System.Collections.Generic/SortedDictionaryTest.cs
 System.Collections.Generic/SortedListTest.cs
 System.Collections.Specialized/BasicOperationsTest.cs
 System.Collections.Specialized/BitVector32Test.cs
index 13946d7a26185e354ca78ff43e7a852cd3a0e708..89e475b30fffbf8f2504a378ee58000f29d3455e 100644 (file)
@@ -1,3 +1,7 @@
+2006-04-05  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * SortedDictionaryTest.cs : new test.
+
 2005-11-10  Zoltan Varga  <vargaz@gmail.com>
 
        * StackTest.cs QueueTest.cs: Remove tests for removed TrimToSize ()
diff --git a/mcs/class/System/Test/System.Collections.Generic/SortedDictionaryTest.cs b/mcs/class/System/Test/System.Collections.Generic/SortedDictionaryTest.cs
new file mode 100644 (file)
index 0000000..52df3f6
--- /dev/null
@@ -0,0 +1,429 @@
+//
+// SortedDictionaryTest.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2006 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.Collections.Generic;
+using System.Runtime.Serialization;
+
+using NUnit.Framework;
+
+namespace MonoTests.System.Collections.Generic
+{
+       [TestFixture]
+        public class SortedDictionaryTest
+       {
+               [Test]
+               public void CtorNullComparer ()
+               {
+                       SortedDictionary<int,string> sd =
+                               new SortedDictionary<int,string> ((IComparer<int>) null);
+                       Assert.AreEqual (Comparer<int>.Default, sd.Comparer);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void CtorNullDictionary ()
+               {
+                       new SortedDictionary<int,string> (default (IDictionary<int,string>));
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void CtorComparerDictionaryNullComparer ()
+               {
+                       new SortedDictionary<int,string> (default (IDictionary<int,string>), null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void CtorComparerDictionaryNullDictionary ()
+               {
+                       new SortedDictionary<int,string> (null, default (IComparer<int>));
+               }
+
+               [Test]
+               public void CtorDefault ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       Assert.IsNotNull (d.Comparer);
+               }
+
+               [Test]
+               public void CtorDictionary ()
+               {
+                       Dictionary<int,string> src = new Dictionary<int,string> ();
+                       src.Add (0, "Foo");
+                       src.Add (4, "Bar");
+                       src.Add (2, "Baz");
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> (src);
+                       Assert.AreEqual (3, d.Count, "#1");
+                       Assert.AreEqual ("Bar", d [4], "#2");
+                       IDictionaryEnumerator e = d.GetEnumerator ();
+                       Assert.IsTrue (e.MoveNext (), "#3");
+                       Assert.AreEqual ("Foo", e.Value, "#4");
+                       Assert.IsTrue (e.MoveNext (), "#5");
+                       Assert.AreEqual ("Baz", e.Value, "#6");
+                       Assert.IsTrue (e.MoveNext (), "#7");
+                       Assert.AreEqual ("Bar", e.Value, "#8");
+
+                       src.Add (3, "Hoge"); // it does not affect.
+                       Assert.AreEqual (3, d.Count, "#9");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void AddDuplicate ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       d.Add (0, "A");
+                       d.Add (0, "A");
+               }
+
+               [Test]
+               public void AddNullValue ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       d.Add (0, null);
+                       d.Add (1, "A");
+                       d.Add (2, null);
+                       Assert.IsNull (d [0], "#0");
+                       Assert.AreEqual ("A", d [1], "#1");
+                       Assert.IsNull (d [2], "#2");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void AddNullKey ()
+               {
+                       SortedDictionary<string,string> d =
+                               new SortedDictionary<string,string> ();
+                       d.Add (null, null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               [Category ("NotWorking")] // see bug #78019
+               public void AddNullKeyNullable ()
+               {
+                       SortedDictionary<Nullable<int>,string> d =
+                               new SortedDictionary<Nullable<int>,string> ();
+                       d.Add (null, "TEST");
+               }
+
+               [Test]
+               [ExpectedException (typeof (KeyNotFoundException))]
+               public void GetItemNonexistent ()
+               {
+                       SortedDictionary<int,int> d =
+                               new SortedDictionary<int,int> ();
+                       Assert.AreEqual (0, d [0]); // does not exist.
+               }
+
+               [Test]
+               public void SetItemNonexistent ()
+               {
+                       SortedDictionary<int,int> d =
+                               new SortedDictionary<int,int> ();
+                       d [0] = 1;
+                       Assert.AreEqual (1, d.Count);
+               }
+
+               [Test]
+               public void SetItemExistent ()
+               {
+                       SortedDictionary<int,int> d =
+                               new SortedDictionary<int,int> ();
+                       d.Add (0, 0);
+                       Assert.AreEqual (1, d.Count, "#1");
+                       d [0] = 1;
+                       Assert.AreEqual (1, d.Count, "#2");
+                       Assert.AreEqual (1, d [0], "#3");
+               }
+
+               [Test]
+               public void GetEnumerator1 ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       d.Add (3, "B");
+                       d.Add (2, "C");
+                       SortedDictionary<int,string>.Enumerator e = d.GetEnumerator ();
+                       Assert.IsTrue (e.MoveNext (), "#1");
+                       Assert.AreEqual ("A", e.Current.Value, "#2");
+                       Assert.IsTrue (e.MoveNext (), "#3");
+                       Assert.AreEqual ("C", e.Current.Value, "#4");
+                       Assert.IsTrue (e.MoveNext (), "#5");
+                       Assert.AreEqual ("B", e.Current.Value, "#6");
+                       Assert.IsFalse (e.MoveNext (), "#7");
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void GetEnumerator2 ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       d.Add (3, "B");
+                       d.Add (2, "C");
+                       IEnumerator e = d.GetEnumerator ();
+                       d.Add (4, "D");
+                       e.MoveNext ();
+               }
+
+               [Test]
+               public void CustomComparer ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> (
+                                       ReverseComparer<int>.Instance);
+
+                       d.Add (1, "A");
+                       d.Add (3, "B");
+                       d.Add (2, "C");
+                       SortedDictionary<int,string>.Enumerator e = d.GetEnumerator ();
+                       Assert.IsTrue (e.MoveNext (), "#1");
+                       Assert.AreEqual ("B", e.Current.Value, "#2");
+                       Assert.IsTrue (e.MoveNext (), "#3");
+                       Assert.AreEqual ("C", e.Current.Value, "#4");
+                       Assert.IsTrue (e.MoveNext (), "#5");
+                       Assert.AreEqual ("A", e.Current.Value, "#6");
+                       Assert.IsFalse (e.MoveNext (), "#7");
+               }
+
+               [Test]
+               public void Remove ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       Assert.IsFalse (d.Remove (0), "#1");
+                       d.Add (0, "Foo");
+                       Assert.IsTrue (d.Remove (0), "#2");
+                       Assert.IsFalse (d.Remove (0), "#3");
+               }
+
+               [Test]
+               public void TryGetValue ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       string s;
+                       Assert.IsFalse (d.TryGetValue (0, out s), "#1");
+                       Assert.IsNull (s, "#2");
+                       d.Add (0, "Test");
+                       Assert.IsTrue (d.TryGetValue (0, out s), "#3");
+                       Assert.AreEqual ("Test", s, "#4");
+                       Assert.IsFalse (d.TryGetValue (1, out s), "#5");
+                       Assert.IsNull (s, "#6");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void IDictionaryAddKeyNull ()
+               {
+                       IDictionary d = new SortedDictionary<string,string> ();
+                       d.Add (null, "A");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void IDictionaryAddKeyNullValueType ()
+               {
+                       IDictionary d = new SortedDictionary<int,string> ();
+                       d.Add (null, "A");
+               }
+
+               [Test]
+               public void IDictionaryAddValueNull ()
+               {
+                       IDictionary d = new SortedDictionary<string,string> ();
+                       // If we simply check "if (value is TValue)" it won't pass.
+                       d.Add ("A", null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void IDictionaryAddValueNullValueType ()
+               {
+                       IDictionary d = new SortedDictionary<string,int> ();
+                       // If we simply allow null it won't result in ArgumentException.
+                       d.Add ("A", null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void KeysICollectionAdd ()
+               {
+                       SortedDictionary<int,string> d = new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       ICollection<int> col = d.Keys;
+                       col.Add (2);
+               }
+
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void KeysICollectionClear ()
+               {
+                       SortedDictionary<int,string> d = new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       ICollection<int> col = d.Keys;
+                       col.Clear ();
+               }
+
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void KeysICollectionRemove ()
+               {
+                       SortedDictionary<int,string> d = new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       ICollection<int> col = d.Keys;
+                       col.Remove (1);
+               }
+
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void ValuesICollectionAdd ()
+               {
+                       SortedDictionary<int,string> d = new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       ICollection<string> col = d.Values;
+                       col.Add ("B");
+               }
+
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void ValuesICollectionClear ()
+               {
+                       SortedDictionary<int,string> d = new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       ICollection<string> col = d.Values;
+                       col.Clear ();
+               }
+
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void ValuesICollectionRemove ()
+               {
+                       SortedDictionary<int,string> d = new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       ICollection<string> col = d.Values;
+                       col.Remove ("A");
+               }
+
+               [Test]
+               public void KeysGetEnumerator1 ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       d.Add (3, "B");
+                       d.Add (2, "C");
+                       IEnumerator e = d.Keys.GetEnumerator ();
+                       Assert.IsTrue (e.MoveNext (), "#1");
+                       Assert.AreEqual (1, e.Current, "#2");
+                       Assert.IsTrue (e.MoveNext (), "#3");
+                       Assert.AreEqual (2, e.Current, "#4");
+                       Assert.IsTrue (e.MoveNext (), "#5");
+                       Assert.AreEqual (3, e.Current, "#6");
+                       Assert.IsFalse (e.MoveNext (), "#7");
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void KeysGetEnumerator2 ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       d.Add (3, "B");
+                       d.Add (2, "C");
+                       IEnumerator e = d.Keys.GetEnumerator ();
+                       d.Add (4, "D");
+                       e.MoveNext ();
+               }
+
+               [Test]
+               public void ValuesGetEnumerator1 ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       d.Add (3, "B");
+                       d.Add (2, "C");
+                       IEnumerator e = d.Values.GetEnumerator ();
+                       Assert.IsTrue (e.MoveNext (), "#1");
+                       Assert.AreEqual ("A", e.Current, "#2");
+                       Assert.IsTrue (e.MoveNext (), "#3");
+                       Assert.AreEqual ("C", e.Current, "#4");
+                       Assert.IsTrue (e.MoveNext (), "#5");
+                       Assert.AreEqual ("B", e.Current, "#6");
+                       Assert.IsFalse (e.MoveNext (), "#7");
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void ValuesGetEnumerator2 ()
+               {
+                       SortedDictionary<int,string> d =
+                               new SortedDictionary<int,string> ();
+                       d.Add (1, "A");
+                       d.Add (3, "B");
+                       d.Add (2, "C");
+                       IEnumerator e = d.Values.GetEnumerator ();
+                       d.Add (4, "D");
+                       e.MoveNext ();
+               }
+       }
+
+       class ReverseComparer<T> : IComparer<T>
+       {
+               static ReverseComparer<T> instance = new ReverseComparer<T> ();
+               public static ReverseComparer<T> Instance {
+                       get { return instance; }
+               }
+
+               ReverseComparer ()
+               {
+               }
+
+               public int Compare (T t1, T t2)
+               {
+                       return Comparer<T>.Default.Compare (t2, t1);
+               }
+       }
+}
+
+#endif