System.Collections.Generic.Collection added
authorCarlos Alberto Cortez <calberto.cortez@gmail.com>
Wed, 1 Sep 2004 23:41:24 +0000 (23:41 -0000)
committerCarlos Alberto Cortez <calberto.cortez@gmail.com>
Wed, 1 Sep 2004 23:41:24 +0000 (23:41 -0000)
svn path=/trunk/mcs/; revision=33189

mcs/class/corlib/System.Collections.Generic/Collection.cs [new file with mode: 0644]

diff --git a/mcs/class/corlib/System.Collections.Generic/Collection.cs b/mcs/class/corlib/System.Collections.Generic/Collection.cs
new file mode 100644 (file)
index 0000000..f9e372a
--- /dev/null
@@ -0,0 +1,417 @@
+//\r
+// System.Collections.Generic.Collection\r
+//\r
+// Author:\r
+//    Carlos Alberto Cortez (carlos@unixmexico.org)\r
+//\r
+// (C) 2004 Carlos Alberto Cortez\r
+//\r
+\r
+//\r
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+//\r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+#if NET_2_0\r
+using System;\r
+using System.Collections;\r
+using System.Collections.Generic;\r
+using System.Runtime.InteropServices;\r
+\r
+namespace System.Collections.Generic \r
+{\r
+\r
+       [CLSCompliant(false)]\r
+       [ComVisible(false)]\r
+       public class Collection <T> : ICollection <T>, IEnumerable <T>, IList <T>,\r
+                       ICollection, IEnumerable, IList\r
+       {\r
+\r
+               private const int defaultLength = 16;\r
+\r
+               private T [] contents;\r
+               private readonly Type innertype;\r
+               private int capacity;\r
+               private int count;\r
+               private int modcount;\r
+\r
+               public Collection ()\r
+               {\r
+                       contents = new T [defaultLength];\r
+                       capacity = defaultLength;\r
+                       innertype = typeof (T);\r
+               }\r
+\r
+               public Collection (List <T> list)\r
+               {\r
+                       if (list == null)\r
+                               throw new ArgumentNullException ("list");\r
+\r
+                       contents = new T [list.Count * 2];\r
+                       list.CopyTo (contents, 0);\r
+                       count = list.Count;\r
+\r
+                       capacity = contents.Length;\r
+                       innertype = typeof (T);\r
+                               \r
+               }\r
+               \r
+               public void Add (T item)\r
+               {\r
+                       if (count >= capacity)\r
+                               Resize (capacity * 2);\r
+                       \r
+                       InsertItem (count, item);\r
+\r
+               }\r
+\r
+               public void Clear ()\r
+               {\r
+                       ClearItems ();\r
+               }\r
+\r
+               protected virtual void ClearItems ()\r
+               {\r
+                       modcount++;\r
+                       if (count <= 0)\r
+                               return;\r
+\r
+                       Array.Clear (contents, 0, count);\r
+                       count = 0;\r
+               }\r
+\r
+               public bool Contains (T item)\r
+               {\r
+                       int index = IndexOf (item);\r
+                       if (index < 0)\r
+                               return false;\r
+\r
+                       return true;\r
+               }\r
+\r
+               public void CopyTo (T [] array, int index)\r
+               {\r
+                       if (array == null)\r
+                               throw new ArgumentNullException ("array");\r
+                       if (index < 0)\r
+                               throw new ArgumentOutOfRangeException ("index");\r
+                       if (count < 0)\r
+                               return;\r
+\r
+                       Array.Copy (contents, 0, array, index, count);\r
+               }\r
+\r
+               public IEnumerator<T> GetEnumerator ()\r
+               {\r
+                       return new Enumerator (this);\r
+               }\r
+\r
+               void ICollection.CopyTo (Array array, int index)\r
+               {\r
+                       if (array == null)\r
+                               throw new ArgumentNullException ("array");\r
+                       if (array.Rank > 1)\r
+                               throw new ArgumentException ("Only single dimension arrays are supported.","array");\r
+\r
+                       CopyTo ((T []) array, index);\r
+               }\r
+\r
+               IEnumerator IEnumerable.GetEnumerator ()\r
+               {\r
+                       return new Enumerator (this);\r
+               }\r
+\r
+               int IList.Add (object value)\r
+               {\r
+                       int pos = count;\r
+                       CheckType (value);\r
+                       Add ((T) value);\r
+\r
+                       return pos;\r
+               }\r
+\r
+               bool IList.Contains (object value)\r
+               {\r
+                       CheckType (value);\r
+                       return Contains ((T) value);\r
+               }\r
+\r
+               int IList.IndexOf (object value)\r
+               {\r
+                       CheckType (value);\r
+                       return IndexOf ((T) value);\r
+               }\r
+\r
+               void IList.Insert (int index, object value)\r
+               {\r
+                       CheckType (value);\r
+                       Insert (index, (T) value);\r
+               }\r
+\r
+               void IList.Remove (object value)\r
+               {\r
+                       CheckType (value);\r
+                       Remove ((T) value);\r
+               }\r
+\r
+               public int IndexOf (T item)\r
+               {\r
+                       for (int i = 0; i < count; i++)\r
+                               if (contents [i].Equals (item))\r
+                                       return i;\r
+\r
+                       return -1;\r
+               }\r
+\r
+               public void Insert (int index, T item)\r
+               {\r
+                       if (index < 0 || index > count)\r
+                               throw new ArgumentOutOfRangeException ("index");\r
+\r
+                       if (count >= capacity)\r
+                               Resize (capacity * 2);\r
+\r
+                       InsertItem (index, item);\r
+\r
+               }\r
+\r
+               protected virtual void InsertItem (int index, T item)\r
+               {\r
+                       modcount++;\r
+                       //\r
+                       // Shift them by 1\r
+                       //\r
+                       int rest = count - index;\r
+                       if (rest > 0)\r
+                               Array.Copy (contents, index, contents, index + 1, rest);\r
+\r
+                       contents [index] = item;\r
+                       count++;\r
+               }\r
+\r
+               public bool Remove (T item)\r
+               {\r
+                       int index = IndexOf (item);\r
+                       if (index > -1) {\r
+                               RemoveItem (index);\r
+                               return true;\r
+                       }\r
+                       \r
+                       return false;\r
+               }\r
+\r
+               public void RemoveAt (int index)\r
+               {\r
+                       if (index < 0 || index >= count)\r
+                               throw new ArgumentOutOfRangeException ("index");\r
+\r
+                       RemoveItem (index);\r
+                       \r
+               }\r
+\r
+               protected virtual void RemoveItem (int index)\r
+               {\r
+                       modcount++;\r
+                       \r
+                       int rest = count - index - 1;\r
+                       if (rest > 0)\r
+                               Array.Copy (contents, index + 1, contents, index, rest);\r
+                       //\r
+                       // Clear the last element\r
+                       //\r
+                       Array.Clear (contents, --count, 1);\r
+               }\r
+\r
+               protected virtual void SetItem (int index, T item)\r
+               {\r
+                       modcount++;\r
+                       contents [index] = item;\r
+               }\r
+\r
+               public int Count {\r
+\r
+                       get {\r
+                               return count;\r
+                       }\r
+                       \r
+               }\r
+\r
+               public T this [int index] {\r
+\r
+                       get {\r
+                               if (index < 0 || index >= count)\r
+                                       throw new ArgumentOutOfRangeException ("index");        \r
+                               return contents [index];\r
+                       }\r
+\r
+                       set {\r
+                               if (index < 0 || index >= count)\r
+                                       throw new ArgumentOutOfRangeException ("index");\r
+                               SetItem (index, value);\r
+                       }\r
+                       \r
+               }\r
+\r
+               object IList.this [int index] {\r
+\r
+                       get {\r
+                               return this [index];\r
+                       }\r
+\r
+                       set {\r
+                               CheckType(value);\r
+                               this [index] = (T) value;\r
+                       }\r
+\r
+               }\r
+\r
+               //\r
+               // We could try to make List.contents internal,\r
+               // avoiding the box and unbox when copying\r
+               //\r
+               protected List <T> Items {\r
+\r
+                       get {\r
+                               return new List <T> (this);\r
+                       }\r
+                       \r
+               }\r
+\r
+               public bool IsFixedSize {\r
+\r
+                       get {\r
+                               return false;\r
+                       }\r
+\r
+               }\r
+\r
+               public bool IsReadOnly {\r
+                       \r
+                       get {\r
+                               return false;\r
+                       }\r
+                       \r
+               }\r
+\r
+               public bool IsSynchronized {\r
+                       \r
+                       get {\r
+                               return false;\r
+                       }\r
+                       \r
+               }\r
+\r
+               public object SyncRoot {\r
+                       \r
+                       get {\r
+                               return this;\r
+                       }\r
+                       \r
+               }\r
+\r
+               private void CheckType (object value)\r
+               {\r
+                       if (!innertype.IsInstanceOfType (value)) {\r
+                               string valtype = value.GetType ().ToString ();\r
+                               throw new ArgumentException (\r
+                                               String.Format ("A value of type {0} can't be used in this generic collection.", valtype),\r
+                                               "value");\r
+                       }\r
+               }\r
+\r
+               private void Resize (int newCapacity)\r
+               {\r
+                       T [] tmp = new T [newCapacity];\r
+                       Array.Copy (contents, tmp, count);\r
+                       contents = tmp;\r
+                       capacity = newCapacity;\r
+               }\r
+               \r
+               //\r
+               // Will we use this iterator until iterators support is done?\r
+               //\r
+               private struct Enumerator : IEnumerator <T>, IEnumerator \r
+               {\r
+\r
+                       private Collection <T> collection;\r
+                       private int current;\r
+                       private int modcount;\r
+\r
+                       public Enumerator (Collection <T> collection)\r
+                       {\r
+                               this.collection = collection;\r
+                               modcount = collection.modcount;\r
+                               current = -1;\r
+                       }\r
+\r
+                       public void Dispose()\r
+                       {\r
+                               modcount = -1;\r
+                       }\r
+\r
+                       object IEnumerator.Current {\r
+\r
+                               get {\r
+                                       return Current;\r
+                               }\r
+                       \r
+                       }\r
+\r
+                       void IEnumerator.Reset ()\r
+                       {\r
+                               if (modcount != collection.modcount)\r
+                                       throw new InvalidOperationException \r
+                                               ("Collection was modified while enumerating.");\r
+\r
+                               current = -1;\r
+                       }\r
+\r
+                       public bool MoveNext ()\r
+                       {\r
+                               if (modcount != collection.modcount)\r
+                                       throw new InvalidOperationException \r
+                                               ("Collection was modified while enumerating.");\r
+                               \r
+                               current++;\r
+                               return current < collection.count;\r
+                       }\r
+\r
+                       public T Current {\r
+\r
+                               get {\r
+                                       if (current < 0 || current >= collection.count)\r
+                                               throw new InvalidOperationException \r
+                                                       ("Collection was modified while enumerating.");\r
+\r
+                                       return collection.contents [current];\r
+                               }\r
+\r
+                       }\r
+\r
+               }\r
+               \r
+       }\r
+\r
+\r
+}\r
+\r
+#endif\r
+\r