2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / class / corlib / System.Collections / ArrayList.cs
blobbafb76aaf91bfcd30b4fe9c3e60ab567cc48a6e4
1 // ArrayList.cs
2 //
3 // Implementation of the ECMA ArrayList.
4 //
5 // Copyright (c) 2003 Thong (Tum) Nguyen [tum@veridicus.com]
6 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 using System.Runtime.InteropServices;
29 using System.Diagnostics;
31 namespace System.Collections
33 [ComVisible(true)]
34 [DebuggerDisplay ("Count={Count}")]
35 [DebuggerTypeProxy (typeof (CollectionDebuggerView))]
36 [Serializable]
37 #if INSIDE_CORLIB
38 public
39 #else
40 internal
41 #endif
42 class ArrayList
43 : IList, ICloneable, ICollection, IEnumerable
45 #region Enumerator
47 private sealed class ArrayListEnumerator
48 : IEnumerator, ICloneable
50 private int m_Pos;
51 private int m_Index;
52 private int m_Count;
53 private object m_Current;
54 private ArrayList m_List;
55 private int m_ExpectedStateChanges;
57 public ArrayListEnumerator(ArrayList list)
58 : this(list, 0, list.Count)
62 public object Clone()
64 return this.MemberwiseClone();
67 public ArrayListEnumerator(ArrayList list, int index, int count)
69 m_List = list;
70 m_Index = index;
71 m_Count = count;
72 m_Pos = m_Index - 1;
73 m_Current = null;
74 m_ExpectedStateChanges = list._version;
77 public object Current
79 get
81 if (m_Pos == m_Index - 1) {
82 throw new InvalidOperationException("Enumerator unusable (Reset pending, or past end of array.");
85 return m_Current;
89 public bool MoveNext()
91 if (m_List._version != m_ExpectedStateChanges)
93 throw new InvalidOperationException("List has changed.");
96 m_Pos++;
98 if (m_Pos - m_Index < m_Count)
100 m_Current = m_List[m_Pos];
102 return true;
105 return false;
108 public void Reset()
110 m_Current = null;
111 m_Pos = m_Index - 1;
115 sealed class SimpleEnumerator : IEnumerator, ICloneable
117 ArrayList list;
118 int index;
119 int version;
120 object currentElement;
121 static object endFlag = new object ();
123 public SimpleEnumerator (ArrayList list)
125 this.list = list;
126 index = -1;
127 version = list._version;
128 currentElement = endFlag;
131 public object Clone ()
133 return MemberwiseClone ();
136 public bool MoveNext ()
138 if (version != list._version)
139 throw new InvalidOperationException("List has changed.");
141 if (++index < list.Count) {
142 currentElement = list [index];
143 return true;
144 } else {
145 currentElement = endFlag;
146 return false;
150 public object Current {
151 get {
152 if (currentElement == endFlag) {
153 if (index == -1)
154 throw new InvalidOperationException ("Enumerator not started");
155 else
156 throw new InvalidOperationException ("Enumerator ended");
159 return currentElement;
163 public void Reset ()
165 if (version != list._version)
166 throw new InvalidOperationException ("List has changed.");
168 currentElement = endFlag;
169 index = -1;
173 #endregion
175 #region ArrayListAdapter
177 /// <summary>
178 /// Adapts various ILists into an ArrayList.
179 /// </summary>
180 [Serializable]
181 private sealed class ArrayListAdapter
182 : ArrayList
184 private sealed class EnumeratorWithRange
185 : IEnumerator, ICloneable
187 private int m_StartIndex;
188 private int m_Count;
189 private int m_MaxCount;
190 private IEnumerator m_Enumerator;
192 public EnumeratorWithRange(IEnumerator enumerator, int index, int count)
194 m_Count = 0;
195 m_StartIndex = index;
196 m_MaxCount = count;
197 m_Enumerator = enumerator;
199 Reset();
202 public object Clone()
204 return this.MemberwiseClone();
207 public object Current
209 get
211 return m_Enumerator.Current;
215 public bool MoveNext()
217 if (m_Count >= m_MaxCount)
219 return false;
222 m_Count++;
224 return m_Enumerator.MoveNext();
227 public void Reset()
229 m_Count = 0;
230 m_Enumerator.Reset();
232 for (int i = 0; i < m_StartIndex; i++)
234 m_Enumerator.MoveNext();
239 private IList m_Adaptee;
241 public ArrayListAdapter(IList adaptee)
242 : base(0, true)
244 m_Adaptee = adaptee;
247 public override object this[int index]
249 get
251 return m_Adaptee[index];
254 set
256 m_Adaptee[index] = value;
260 public override int Count
262 get
264 return m_Adaptee.Count;
268 public override int Capacity
270 get
272 return m_Adaptee.Count;
275 set
277 if (value < m_Adaptee.Count)
279 throw new ArgumentException("capacity");
284 public override bool IsFixedSize
286 get
288 return m_Adaptee.IsFixedSize;
292 public override bool IsReadOnly
294 get
296 return m_Adaptee.IsReadOnly;
300 public override object SyncRoot
302 get
304 return m_Adaptee.SyncRoot;
308 public override int Add(object value)
310 return m_Adaptee.Add(value);
313 public override void Clear()
315 m_Adaptee.Clear();
318 public override bool Contains(object value)
320 return m_Adaptee.Contains(value);
323 public override int IndexOf(object value)
325 return m_Adaptee.IndexOf(value);
328 public override int IndexOf(object value, int startIndex)
330 return IndexOf(value, startIndex, m_Adaptee.Count - startIndex);
333 public override int IndexOf(object value, int startIndex, int count)
335 if (startIndex < 0 || startIndex > m_Adaptee.Count)
337 ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
338 "Does not specify valid index.");
341 if (count < 0)
343 ThrowNewArgumentOutOfRangeException ("count", count,
344 "Can't be less than 0.");
347 // re-ordered to avoid possible integer overflow
348 if (startIndex > m_Adaptee.Count - count) {
349 // LAMESPEC: Every other method throws ArgumentException
350 throw new ArgumentOutOfRangeException("count",
351 "Start index and count do not specify a valid range.");
354 if (value == null)
356 for (int i = startIndex; i < startIndex + count; i++)
358 if (m_Adaptee[i] == null)
360 return i;
364 else
366 for (int i = startIndex; i < startIndex + count; i++)
368 if (value.Equals(m_Adaptee[i]))
370 return i;
375 return -1;
378 public override int LastIndexOf(object value)
380 return LastIndexOf(value, m_Adaptee.Count - 1);
383 public override int LastIndexOf(object value, int startIndex)
385 return LastIndexOf(value, startIndex, startIndex + 1);
388 public override int LastIndexOf(object value, int startIndex, int count)
390 if (startIndex < 0)
392 ThrowNewArgumentOutOfRangeException ("startIndex", startIndex, "< 0");
395 if (count < 0)
397 ThrowNewArgumentOutOfRangeException ("count", count, "count is negative.");
400 if (startIndex - count + 1 < 0)
402 ThrowNewArgumentOutOfRangeException ("count", count, "count is too large.");
405 if (value == null)
407 for (int i = startIndex; i > startIndex - count; i--)
409 if (m_Adaptee[i] == null)
411 return i;
415 else
417 for (int i = startIndex; i > startIndex - count; i--)
419 if (value.Equals(m_Adaptee[i]))
421 return i;
426 return -1;
429 public override void Insert(int index, object value)
431 m_Adaptee.Insert(index, value);
434 public override void InsertRange(int index, ICollection c)
436 if (c == null)
438 throw new ArgumentNullException("c");
441 if (index > m_Adaptee.Count)
443 ThrowNewArgumentOutOfRangeException ("index", index,
444 "Index must be >= 0 and <= Count.");
447 foreach (object value in c)
449 m_Adaptee.Insert(index++, value);
453 public override void Remove(object value)
455 m_Adaptee.Remove(value);
458 public override void RemoveAt(int index)
460 m_Adaptee.RemoveAt(index);
463 public override void RemoveRange(int index, int count)
465 CheckRange(index, count, m_Adaptee.Count);
467 for (int i = 0; i < count; i++)
469 m_Adaptee.RemoveAt(index);
473 public override void Reverse()
475 Reverse(0, m_Adaptee.Count);
478 public override void Reverse(int index, int count)
480 object tmp;
482 CheckRange(index, count, m_Adaptee.Count);
484 for (int i = 0; i < count / 2; i++)
486 tmp = m_Adaptee[i + index];
487 m_Adaptee[i + index] = m_Adaptee[(index + count) - i + index - 1];
488 m_Adaptee[(index + count) - i + index - 1] = tmp;
492 public override void SetRange(int index, ICollection c)
494 if (c == null)
496 throw new ArgumentNullException("c");
499 if (index < 0 || index + c.Count > m_Adaptee.Count)
501 throw new ArgumentOutOfRangeException("index");
504 int x = index;
506 foreach (object value in c)
508 m_Adaptee[x++] = value;
512 public override void CopyTo(System.Array array)
514 m_Adaptee.CopyTo(array, 0);
517 public override void CopyTo(System.Array array, int index)
519 m_Adaptee.CopyTo(array, index);
522 public override void CopyTo(int index, System.Array array, int arrayIndex, int count)
524 if (index < 0)
526 ThrowNewArgumentOutOfRangeException ("index", index,
527 "Can't be less than zero.");
530 if (arrayIndex < 0)
532 ThrowNewArgumentOutOfRangeException ("arrayIndex", arrayIndex,
533 "Can't be less than zero.");
536 if (count < 0)
538 ThrowNewArgumentOutOfRangeException ("index", index,
539 "Can't be less than zero.");
542 if (index >= m_Adaptee.Count)
544 throw new ArgumentException("Can't be more or equal to list count.",
545 "index");
548 if (array.Rank > 1)
550 throw new ArgumentException("Can't copy into multi-dimensional array.");
553 if (arrayIndex >= array.Length)
555 throw new ArgumentException("arrayIndex can't be greater than array.Length - 1.");
558 if (array.Length - arrayIndex + 1 < count)
560 throw new ArgumentException("Destination array is too small.");
563 // re-ordered to avoid possible integer overflow
564 if (index > m_Adaptee.Count - count) {
565 throw new ArgumentException("Index and count do not denote a valid range of elements.", "index");
568 for (int i = 0; i < count; i++)
570 array.SetValue(m_Adaptee[index + i], arrayIndex + i);
574 public override bool IsSynchronized
576 get
578 return m_Adaptee.IsSynchronized;
582 public override IEnumerator GetEnumerator()
584 return m_Adaptee.GetEnumerator();
587 public override IEnumerator GetEnumerator(int index, int count)
589 CheckRange(index, count, m_Adaptee.Count);
591 return new EnumeratorWithRange(m_Adaptee.GetEnumerator(), index, count);
594 public override void AddRange(ICollection c)
596 foreach (object value in c)
598 m_Adaptee.Add(value);
602 public override int BinarySearch(object value)
604 return BinarySearch(value, null);
607 public override int BinarySearch(object value, IComparer comparer)
609 return BinarySearch(0, m_Adaptee.Count, value, comparer);
612 public override int BinarySearch(int index, int count, object value, IComparer comparer)
614 int r, x, y, z;
616 // Doing a direct BinarySearch on the adaptee will perform poorly if the adaptee is a linked-list.
617 // Alternatives include copying the adaptee to a temporary array first.
619 CheckRange(index, count, m_Adaptee.Count);
621 if (comparer == null)
623 comparer = Comparer.Default;
626 x = index;
627 y = index + count - 1;
629 while (x <= y)
631 // Be careful with overflows
632 z = x + ((y - x) / 2);
634 r = comparer.Compare(value, m_Adaptee[z]);
636 if (r < 0)
638 y = z - 1;
640 else if (r > 0)
642 x = z + 1;
644 else
646 return z;
650 return ~x;
653 public override object Clone()
655 return new ArrayList.ArrayListAdapter(m_Adaptee);
658 public override ArrayList GetRange(int index, int count)
660 CheckRange(index, count, m_Adaptee.Count);
662 return new RangedArrayList(this, index, count);
665 public override void TrimToSize()
667 // N/A
670 public override void Sort()
672 Sort(Comparer.Default);
675 public override void Sort(IComparer comparer)
677 Sort(0, m_Adaptee.Count, comparer);
680 public override void Sort(int index, int count, IComparer comparer)
682 CheckRange(index, count, m_Adaptee.Count);
684 if (comparer == null)
686 comparer = Comparer.Default;
689 // Doing a direct sort on the adaptee will perform poorly if the adaptee is a linked-list.
690 // Alternatives include copying the adaptee into a temporary array first.
692 QuickSort(m_Adaptee, index, index + count - 1, comparer);
696 /// <summary>
697 /// Swaps two items in a list at the specified indexes.
698 /// </summary>
699 private static void Swap(IList list, int x, int y)
701 object tmp;
703 tmp = list[x];
704 list[x] = list[y];
705 list[y] = tmp;
708 /// <summary>
709 /// Quicksort for lists.
710 /// </summary>
711 /// <remarks>
712 /// This function acts as both qsort() and partition().
713 /// </remarks>
714 internal static void QuickSort(IList list, int left, int right, IComparer comparer)
716 int i, j, middle;
717 object pivot;
719 if (left >= right)
721 return;
724 // Pick the pivot using the median-of-three strategy.
726 // Be careful with overflows
727 middle = left + ((right - left) / 2);
729 if (comparer.Compare(list[middle], list[left]) < 0)
731 Swap(list, middle, left);
734 if (comparer.Compare(list[right], list[left]) < 0)
736 Swap(list, right, left);
739 if (comparer.Compare(list[right], list[middle]) < 0)
741 Swap(list, right, middle);
744 if (right - left + 1 <= 3)
746 return;
749 // Put the pivot in right - 1.
750 Swap(list, right - 1, middle);
752 // List should look like:
754 // [Small] ..Numbers.. [Middle] ..Numbers.. [Pivot][Large]
756 pivot = list[right - 1];
758 // Sort from (left + 1) to (right - 2).
760 i = left;
761 j = right - 1;
763 for (;;)
765 while (comparer.Compare(list[++i], pivot) < 0);
766 while (comparer.Compare(list[--j], pivot) > 0);
768 if (i < j)
770 Swap(list, i, j);
772 else
774 break;
778 // Put pivot into the right position (real middle).
780 Swap(list, right - 1, i);
782 // Recursively sort the left and right sub lists.
784 QuickSort(list, left, i - 1, comparer);
785 QuickSort(list, i + 1, right, comparer);
788 public override object[] ToArray()
790 object[] retval;
792 retval = new object[m_Adaptee.Count];
794 m_Adaptee.CopyTo(retval, 0);
796 return retval;
799 public override Array ToArray(Type elementType)
801 Array retval;
803 retval = Array.CreateInstance(elementType, m_Adaptee.Count);
805 m_Adaptee.CopyTo(retval, 0);
807 return retval;
811 #endregion // ArrayListAdapter
814 // ArrayList wrappers
817 #region ArrayListWrapper
819 /// <summary>
820 /// Base wrapper/decorator for ArrayLists. Simply delegates all methods to
821 /// the underlying wrappee.
822 /// </summary>
823 [Serializable]
824 private class ArrayListWrapper
825 : ArrayList
827 protected ArrayList m_InnerArrayList;
829 #region Constructors
831 public ArrayListWrapper(ArrayList innerArrayList)
833 m_InnerArrayList = innerArrayList;
836 #endregion
838 #region Indexers
840 public override object this[int index]
842 get
844 return m_InnerArrayList[index];
847 set
849 m_InnerArrayList[index] = value;
853 #endregion
855 #region Properties
857 public override int Count
859 get
861 return m_InnerArrayList.Count;
865 public override int Capacity
867 get
869 return m_InnerArrayList.Capacity;
872 set
874 m_InnerArrayList.Capacity = value;
878 public override bool IsFixedSize
880 get
882 return m_InnerArrayList.IsFixedSize;
886 public override bool IsReadOnly
888 get
890 return m_InnerArrayList.IsReadOnly;
894 public override bool IsSynchronized
896 get
898 return m_InnerArrayList.IsSynchronized;
902 public override object SyncRoot
904 get
906 return m_InnerArrayList.SyncRoot;
910 #endregion
912 #region Methods
914 public override int Add(object value)
916 return m_InnerArrayList.Add(value);
919 public override void Clear()
921 m_InnerArrayList.Clear();
924 public override bool Contains(object value)
926 return m_InnerArrayList.Contains(value);
929 public override int IndexOf(object value)
931 return m_InnerArrayList.IndexOf(value);
934 public override int IndexOf(object value, int startIndex)
936 return m_InnerArrayList.IndexOf(value, startIndex);
939 public override int IndexOf(object value, int startIndex, int count)
941 return m_InnerArrayList.IndexOf(value, startIndex, count);
944 public override int LastIndexOf(object value)
946 return m_InnerArrayList.LastIndexOf(value);
949 public override int LastIndexOf(object value, int startIndex)
951 return m_InnerArrayList.LastIndexOf(value, startIndex);
954 public override int LastIndexOf(object value, int startIndex, int count)
956 return m_InnerArrayList.LastIndexOf(value, startIndex, count);
959 public override void Insert(int index, object value)
961 m_InnerArrayList.Insert(index, value);
964 public override void InsertRange(int index, ICollection c)
966 m_InnerArrayList.InsertRange(index, c);
969 public override void Remove(object value)
971 m_InnerArrayList.Remove(value);
974 public override void RemoveAt(int index)
976 m_InnerArrayList.RemoveAt(index);
979 public override void RemoveRange(int index, int count)
981 m_InnerArrayList.RemoveRange(index, count);
984 public override void Reverse()
986 m_InnerArrayList.Reverse();
989 public override void Reverse(int index, int count)
991 m_InnerArrayList.Reverse(index, count);
994 public override void SetRange(int index, ICollection c)
996 m_InnerArrayList.SetRange(index, c);
999 public override void CopyTo(System.Array array)
1001 m_InnerArrayList.CopyTo(array);
1004 public override void CopyTo(System.Array array, int index)
1006 m_InnerArrayList.CopyTo(array, index);
1009 public override void CopyTo(int index, System.Array array, int arrayIndex, int count)
1011 m_InnerArrayList.CopyTo(index, array, arrayIndex, count);
1014 public override IEnumerator GetEnumerator()
1016 return m_InnerArrayList.GetEnumerator();
1019 public override IEnumerator GetEnumerator(int index, int count)
1021 return m_InnerArrayList.GetEnumerator(index, count);
1024 public override void AddRange(ICollection c)
1026 m_InnerArrayList.AddRange(c);
1029 public override int BinarySearch(object value)
1031 return m_InnerArrayList.BinarySearch(value);
1034 public override int BinarySearch(object value, IComparer comparer)
1036 return m_InnerArrayList.BinarySearch(value, comparer);
1039 public override int BinarySearch(int index, int count, object value, IComparer comparer)
1041 return m_InnerArrayList.BinarySearch(index, count, value, comparer);
1044 public override object Clone()
1046 return m_InnerArrayList.Clone();
1049 public override ArrayList GetRange(int index, int count)
1051 return m_InnerArrayList.GetRange(index, count);
1054 public override void TrimToSize()
1056 m_InnerArrayList.TrimToSize();
1059 public override void Sort()
1061 m_InnerArrayList.Sort();
1064 public override void Sort(IComparer comparer)
1066 m_InnerArrayList.Sort(comparer);
1069 public override void Sort(int index, int count, IComparer comparer)
1071 m_InnerArrayList.Sort(index, count, comparer);
1074 public override object[] ToArray()
1076 return m_InnerArrayList.ToArray();
1079 public override Array ToArray(Type elementType)
1081 return m_InnerArrayList.ToArray(elementType);
1084 #endregion
1087 #endregion
1089 #region SynchronizedArrayListWrapper
1091 /// <summary>
1092 /// ArrayListWrapper that synchronizes calls to all methods/properties.
1093 /// </summary>
1094 /// <remarks>
1095 /// Works by just synchronizing all method calls. In the future careful optimisation
1096 /// could give better performance...
1097 /// </remarks>
1098 [Serializable]
1099 private sealed class SynchronizedArrayListWrapper
1100 : ArrayListWrapper
1102 private object m_SyncRoot;
1104 #region Constructors
1106 /// <summary>
1107 /// Creates a new synchronized wrapper for the given <see cref="ArrayList"/>.
1108 /// </summary>
1109 /// <param name="innerArrayList"></param>
1110 internal SynchronizedArrayListWrapper(ArrayList innerArrayList)
1111 : base(innerArrayList)
1113 m_SyncRoot = innerArrayList.SyncRoot;
1116 #endregion
1118 #region Indexers
1120 public override object this[int index]
1122 get
1124 lock (m_SyncRoot)
1126 return m_InnerArrayList[index];
1130 set
1132 lock (m_SyncRoot)
1134 m_InnerArrayList[index] = value;
1139 #endregion
1141 #region Properties
1143 // Some of these properties may be calculated so it's best to synchronize
1144 // them even though it might cause a performance hit.
1145 // Better safe than sorry ;D.
1147 public override int Count
1149 get
1151 lock (m_SyncRoot)
1153 return m_InnerArrayList.Count;
1158 public override int Capacity
1160 get
1162 lock (m_SyncRoot)
1164 return m_InnerArrayList.Capacity;
1168 set
1170 lock (m_SyncRoot)
1172 m_InnerArrayList.Capacity = value;
1177 public override bool IsFixedSize
1179 get
1181 lock (m_SyncRoot)
1183 return m_InnerArrayList.IsFixedSize;
1188 public override bool IsReadOnly
1190 get
1192 lock (m_SyncRoot)
1194 return m_InnerArrayList.IsReadOnly;
1199 public override bool IsSynchronized
1201 get
1203 return true;
1207 public override object SyncRoot
1209 get
1211 return m_SyncRoot;
1215 #endregion
1217 #region Methods
1219 public override int Add(object value)
1221 lock (m_SyncRoot)
1223 return m_InnerArrayList.Add(value);
1227 public override void Clear()
1229 lock (m_SyncRoot)
1231 m_InnerArrayList.Clear();
1235 public override bool Contains(object value)
1237 lock (m_SyncRoot)
1239 return m_InnerArrayList.Contains(value);
1243 public override int IndexOf(object value)
1245 lock (m_SyncRoot)
1247 return m_InnerArrayList.IndexOf(value);
1251 public override int IndexOf(object value, int startIndex)
1253 lock (m_SyncRoot)
1255 return m_InnerArrayList.IndexOf(value, startIndex);
1259 public override int IndexOf(object value, int startIndex, int count)
1261 lock (m_SyncRoot)
1263 return m_InnerArrayList.IndexOf(value, startIndex, count);
1267 public override int LastIndexOf(object value)
1269 lock (m_SyncRoot)
1271 return m_InnerArrayList.LastIndexOf(value);
1275 public override int LastIndexOf(object value, int startIndex)
1277 lock (m_SyncRoot)
1279 return m_InnerArrayList.LastIndexOf(value, startIndex);
1283 public override int LastIndexOf(object value, int startIndex, int count)
1285 lock (m_SyncRoot)
1287 return m_InnerArrayList.LastIndexOf(value, startIndex, count);
1291 public override void Insert(int index, object value)
1293 lock (m_SyncRoot)
1295 m_InnerArrayList.Insert(index, value);
1299 public override void InsertRange(int index, ICollection c)
1301 lock (m_SyncRoot)
1303 m_InnerArrayList.InsertRange(index, c);
1307 public override void Remove(object value)
1309 lock (m_SyncRoot)
1311 m_InnerArrayList.Remove(value);
1315 public override void RemoveAt(int index)
1317 lock (m_SyncRoot)
1319 m_InnerArrayList.RemoveAt(index);
1323 public override void RemoveRange(int index, int count)
1325 lock (m_SyncRoot)
1327 m_InnerArrayList.RemoveRange(index, count);
1331 public override void Reverse()
1333 lock (m_SyncRoot)
1335 m_InnerArrayList.Reverse();
1339 public override void Reverse(int index, int count)
1341 lock (m_SyncRoot)
1343 m_InnerArrayList.Reverse(index, count);
1347 public override void CopyTo(System.Array array)
1349 lock (m_SyncRoot)
1351 m_InnerArrayList.CopyTo(array);
1355 public override void CopyTo(System.Array array, int index)
1357 lock (m_SyncRoot)
1359 m_InnerArrayList.CopyTo(array, index);
1363 public override void CopyTo(int index, System.Array array, int arrayIndex, int count)
1365 lock (m_SyncRoot)
1367 m_InnerArrayList.CopyTo(index, array, arrayIndex, count);
1371 public override IEnumerator GetEnumerator()
1373 lock (m_SyncRoot)
1375 return m_InnerArrayList.GetEnumerator();
1379 public override IEnumerator GetEnumerator(int index, int count)
1381 lock (m_SyncRoot)
1383 return m_InnerArrayList.GetEnumerator(index, count);
1387 public override void AddRange(ICollection c)
1389 lock (m_SyncRoot)
1391 m_InnerArrayList.AddRange(c);
1395 public override int BinarySearch(object value)
1397 lock (m_SyncRoot)
1399 return m_InnerArrayList.BinarySearch(value);
1403 public override int BinarySearch(object value, IComparer comparer)
1405 lock (m_SyncRoot)
1407 return m_InnerArrayList.BinarySearch(value, comparer);
1411 public override int BinarySearch(int index, int count, object value, IComparer comparer)
1413 lock (m_SyncRoot)
1415 return m_InnerArrayList.BinarySearch(index, count, value, comparer);
1419 public override object Clone()
1421 lock (m_SyncRoot)
1423 return m_InnerArrayList.Clone();
1427 public override ArrayList GetRange(int index, int count)
1429 lock (m_SyncRoot)
1431 return m_InnerArrayList.GetRange(index, count);
1435 public override void TrimToSize()
1437 lock (m_SyncRoot)
1439 m_InnerArrayList.TrimToSize();
1443 public override void Sort()
1445 lock (m_SyncRoot)
1447 m_InnerArrayList.Sort();
1451 public override void Sort(IComparer comparer)
1453 lock (m_SyncRoot)
1455 m_InnerArrayList.Sort(comparer);
1459 public override void Sort(int index, int count, IComparer comparer)
1461 lock (m_SyncRoot)
1463 m_InnerArrayList.Sort(index, count, comparer);
1467 public override object[] ToArray()
1469 lock (m_SyncRoot)
1471 return m_InnerArrayList.ToArray();
1475 public override Array ToArray(Type elementType)
1477 lock (m_SyncRoot)
1479 return m_InnerArrayList.ToArray(elementType);
1483 #endregion
1486 #endregion
1488 #region FixedSizeArrayListWrapper
1490 [Serializable]
1491 private class FixedSizeArrayListWrapper
1492 : ArrayListWrapper
1494 #region Constructors
1496 public FixedSizeArrayListWrapper(ArrayList innerList)
1497 : base(innerList)
1501 #endregion
1503 #region Properties
1505 /// <summary>
1506 /// Gets the error message to display when an readonly/fixedsize related exception is
1507 /// thrown.
1508 /// </summary>
1509 protected virtual string ErrorMessage
1511 get
1513 return "Can't add or remove from a fixed-size list.";
1517 public override int Capacity
1519 get
1521 return base.Capacity;
1524 set
1526 throw new NotSupportedException(this.ErrorMessage);
1530 public override bool IsFixedSize
1532 get
1534 return true;
1538 #endregion
1540 #region Methods
1542 public override int Add(object value)
1544 throw new NotSupportedException(this.ErrorMessage);
1547 public override void AddRange(ICollection c)
1549 throw new NotSupportedException(this.ErrorMessage);
1552 public override void Clear()
1554 throw new NotSupportedException(this.ErrorMessage);
1557 public override void Insert(int index, object value)
1559 throw new NotSupportedException(this.ErrorMessage);
1562 public override void InsertRange(int index, ICollection c)
1564 throw new NotSupportedException(this.ErrorMessage);
1567 public override void Remove(object value)
1569 throw new NotSupportedException(this.ErrorMessage);
1572 public override void RemoveAt(int index)
1574 throw new NotSupportedException(this.ErrorMessage);
1577 public override void RemoveRange(int index, int count)
1579 throw new NotSupportedException(this.ErrorMessage);
1582 public override void TrimToSize()
1584 throw new NotSupportedException(this.ErrorMessage);
1587 #endregion
1590 #endregion
1592 #region ReadOnlyArrayListWrapper
1594 [Serializable]
1595 private sealed class ReadOnlyArrayListWrapper
1596 : FixedSizeArrayListWrapper
1598 protected override string ErrorMessage
1600 get
1602 return "Can't modify a readonly list.";
1606 public override bool IsReadOnly
1608 get
1610 return true;
1614 public ReadOnlyArrayListWrapper(ArrayList innerArrayList)
1615 : base(innerArrayList)
1619 public override object this[int index]
1621 get
1623 return m_InnerArrayList[index];
1626 set
1628 throw new NotSupportedException(this.ErrorMessage);
1632 public override void Reverse()
1634 throw new NotSupportedException(this.ErrorMessage);
1637 public override void Reverse(int index, int count)
1639 throw new NotSupportedException(this.ErrorMessage);
1642 public override void SetRange(int index, ICollection c)
1644 throw new NotSupportedException(this.ErrorMessage);
1647 public override void Sort()
1649 throw new NotSupportedException(this.ErrorMessage);
1652 public override void Sort(IComparer comparer)
1654 throw new NotSupportedException(this.ErrorMessage);
1657 public override void Sort(int index, int count, IComparer comparer)
1659 throw new NotSupportedException(this.ErrorMessage);
1663 #endregion
1665 #region RangedArrayList
1667 [Serializable]
1668 private sealed class RangedArrayList
1669 : ArrayListWrapper
1671 private int m_InnerIndex;
1672 private int m_InnerCount;
1673 private int m_InnerStateChanges;
1675 public RangedArrayList(ArrayList innerList, int index, int count)
1676 : base(innerList)
1678 m_InnerIndex = index;
1679 m_InnerCount = count;
1680 m_InnerStateChanges = innerList._version;
1683 #region Indexers
1685 public override bool IsSynchronized
1689 return false;
1693 public override object this[int index]
1695 get
1697 if (index < 0 || index > m_InnerCount)
1699 throw new ArgumentOutOfRangeException("index");
1702 return m_InnerArrayList[m_InnerIndex + index];
1705 set
1707 if (index < 0 || index > m_InnerCount)
1709 throw new ArgumentOutOfRangeException("index");
1712 m_InnerArrayList[m_InnerIndex + index] = value;
1716 #endregion
1718 #region Properties
1720 public override int Count
1722 get
1724 VerifyStateChanges();
1726 return m_InnerCount;
1730 public override int Capacity
1732 get
1734 return m_InnerArrayList.Capacity;
1737 set
1739 if (value < m_InnerCount)
1741 throw new ArgumentOutOfRangeException();
1746 #endregion
1748 #region Methods
1750 private void VerifyStateChanges()
1752 if (m_InnerStateChanges != m_InnerArrayList._version)
1754 throw new InvalidOperationException
1755 ("ArrayList view is invalid because the underlying ArrayList was modified.");
1759 public override int Add(object value)
1761 VerifyStateChanges();
1763 m_InnerArrayList.Insert(m_InnerIndex + m_InnerCount, value);
1765 m_InnerStateChanges = m_InnerArrayList._version;
1767 return ++m_InnerCount;
1770 public override void Clear()
1772 VerifyStateChanges();
1774 m_InnerArrayList.RemoveRange(m_InnerIndex, m_InnerCount);
1775 m_InnerCount = 0;
1777 m_InnerStateChanges = m_InnerArrayList._version;
1780 public override bool Contains(object value)
1782 return m_InnerArrayList.Contains(value, m_InnerIndex, m_InnerCount);
1785 public override int IndexOf(object value)
1787 return IndexOf(value, 0);
1790 public override int IndexOf(object value, int startIndex)
1792 return IndexOf(value, startIndex, m_InnerCount - startIndex);
1795 public override int IndexOf(object value, int startIndex, int count)
1797 if (startIndex < 0 || startIndex > m_InnerCount)
1799 ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
1800 "Does not specify valid index.");
1803 if (count < 0)
1805 ThrowNewArgumentOutOfRangeException ("count", count,
1806 "Can't be less than 0.");
1809 // re-ordered to avoid possible integer overflow
1810 if (startIndex > m_InnerCount - count)
1812 // LAMESPEC: Every other method throws ArgumentException
1814 throw new ArgumentOutOfRangeException("count",
1815 "Start index and count do not specify a valid range.");
1818 int retval = m_InnerArrayList.IndexOf(value, m_InnerIndex + startIndex, count);
1820 if (retval == -1)
1822 return -1;
1824 else
1826 return retval - m_InnerIndex;
1830 public override int LastIndexOf(object value)
1832 return LastIndexOf(value, m_InnerCount - 1);
1835 public override int LastIndexOf(object value, int startIndex)
1837 return LastIndexOf(value, startIndex, startIndex + 1);
1840 public override int LastIndexOf(object value, int startIndex, int count)
1842 if (startIndex < 0)
1844 ThrowNewArgumentOutOfRangeException ("startIndex", startIndex, "< 0");
1847 if (count < 0)
1849 ThrowNewArgumentOutOfRangeException ("count", count, "count is negative.");
1852 int retval = m_InnerArrayList.LastIndexOf(value, m_InnerIndex + startIndex, count);
1854 if (retval == -1)
1856 return -1;
1858 else
1860 return retval - m_InnerIndex;
1864 public override void Insert(int index, object value)
1866 VerifyStateChanges();
1868 if (index < 0 || index > m_InnerCount)
1870 ThrowNewArgumentOutOfRangeException ("index", index,
1871 "Index must be >= 0 and <= Count.");
1874 m_InnerArrayList.Insert(m_InnerIndex + index, value);
1876 m_InnerCount++;
1878 m_InnerStateChanges = m_InnerArrayList._version;
1881 public override void InsertRange(int index, ICollection c)
1883 VerifyStateChanges();
1885 if (index < 0 || index > m_InnerCount)
1887 ThrowNewArgumentOutOfRangeException ("index", index,
1888 "Index must be >= 0 and <= Count.");
1891 m_InnerArrayList.InsertRange(m_InnerIndex + index, c);
1893 m_InnerCount += c.Count;
1895 m_InnerStateChanges = m_InnerArrayList._version;
1898 public override void Remove(object value)
1900 VerifyStateChanges();
1902 int x = IndexOf(value);
1904 if (x > -1)
1906 RemoveAt(x);
1909 m_InnerStateChanges = m_InnerArrayList._version;
1912 public override void RemoveAt(int index)
1914 VerifyStateChanges();
1916 if (index < 0 || index > m_InnerCount)
1918 ThrowNewArgumentOutOfRangeException ("index", index,
1919 "Index must be >= 0 and <= Count.");
1922 m_InnerArrayList.RemoveAt(m_InnerIndex + index);
1924 m_InnerCount--;
1925 m_InnerStateChanges = m_InnerArrayList._version;
1928 public override void RemoveRange(int index, int count)
1930 VerifyStateChanges();
1932 CheckRange(index, count, m_InnerCount);
1934 m_InnerArrayList.RemoveRange(m_InnerIndex + index, count);
1936 m_InnerCount -= count;
1938 m_InnerStateChanges = m_InnerArrayList._version;
1941 public override void Reverse()
1943 Reverse(0, m_InnerCount);
1946 public override void Reverse(int index, int count)
1948 VerifyStateChanges();
1950 CheckRange(index, count, m_InnerCount);
1952 m_InnerArrayList.Reverse(m_InnerIndex + index, count);
1954 m_InnerStateChanges = m_InnerArrayList._version;
1957 public override void SetRange(int index, ICollection c)
1959 VerifyStateChanges();
1961 if (index < 0 || index > m_InnerCount)
1963 ThrowNewArgumentOutOfRangeException ("index", index,
1964 "Index must be >= 0 and <= Count.");
1967 m_InnerArrayList.SetRange(m_InnerIndex + index, c);
1969 m_InnerStateChanges = m_InnerArrayList._version;
1972 public override void CopyTo(System.Array array)
1974 CopyTo(array, 0);
1977 public override void CopyTo(System.Array array, int index)
1979 CopyTo(0, array, index, m_InnerCount);
1982 public override void CopyTo(int index, System.Array array, int arrayIndex, int count)
1984 CheckRange(index, count, m_InnerCount);
1986 m_InnerArrayList.CopyTo(m_InnerIndex + index, array, arrayIndex, count);
1989 public override IEnumerator GetEnumerator()
1991 return GetEnumerator(0, m_InnerCount);
1994 public override IEnumerator GetEnumerator(int index, int count)
1996 CheckRange(index, count, m_InnerCount);
1998 return m_InnerArrayList.GetEnumerator(m_InnerIndex + index, count);
2001 public override void AddRange(ICollection c)
2003 VerifyStateChanges();
2005 m_InnerArrayList.InsertRange(m_InnerCount, c);
2007 m_InnerCount += c.Count;
2009 m_InnerStateChanges = m_InnerArrayList._version;
2012 public override int BinarySearch(object value)
2014 return BinarySearch(0, m_InnerCount, value, Comparer.Default);
2017 public override int BinarySearch(object value, IComparer comparer)
2019 return BinarySearch(0, m_InnerCount, value, comparer);
2022 public override int BinarySearch(int index, int count, object value, IComparer comparer)
2024 CheckRange(index, count, m_InnerCount);
2026 return m_InnerArrayList.BinarySearch(m_InnerIndex + index, count, value, comparer);
2029 public override object Clone()
2031 return new RangedArrayList((ArrayList)m_InnerArrayList.Clone(), m_InnerIndex, m_InnerCount);
2034 public override ArrayList GetRange(int index, int count)
2036 CheckRange(index, count, m_InnerCount);
2038 return new RangedArrayList(this, index, count);
2041 public override void TrimToSize()
2043 throw new NotSupportedException();
2046 public override void Sort()
2048 Sort(Comparer.Default);
2051 public override void Sort(IComparer comparer)
2053 Sort(0, m_InnerCount, comparer);
2056 public override void Sort(int index, int count, IComparer comparer)
2058 VerifyStateChanges();
2060 CheckRange(index, count, m_InnerCount);
2062 m_InnerArrayList.Sort(m_InnerIndex + index, count, comparer);
2064 m_InnerStateChanges = m_InnerArrayList._version;
2067 public override object[] ToArray()
2069 object[] array;
2071 array = new object[m_InnerCount];
2073 m_InnerArrayList.CopyTo (m_InnerIndex, array, 0, m_InnerCount);
2075 return array;
2078 public override Array ToArray(Type elementType)
2080 Array array;
2082 array = Array.CreateInstance(elementType, m_InnerCount);
2084 m_InnerArrayList.CopyTo(m_InnerIndex, array, 0, m_InnerCount);
2086 return array;
2089 #endregion
2092 #endregion
2095 // List wrappers
2098 #region SynchronizedListWrapper
2100 [Serializable]
2101 private sealed class SynchronizedListWrapper
2102 : ListWrapper
2104 private object m_SyncRoot;
2106 public SynchronizedListWrapper(IList innerList)
2107 : base(innerList)
2109 m_SyncRoot = innerList.SyncRoot;
2112 public override int Count
2114 get
2116 lock (m_SyncRoot)
2118 return m_InnerList.Count;
2123 public override bool IsSynchronized
2125 get
2127 return true;
2131 public override object SyncRoot
2133 get
2135 lock (m_SyncRoot)
2137 return m_InnerList.SyncRoot;
2142 public override bool IsFixedSize
2144 get
2146 lock (m_SyncRoot)
2148 return m_InnerList.IsFixedSize;
2153 public override bool IsReadOnly
2155 get
2157 lock (m_SyncRoot)
2159 return m_InnerList.IsReadOnly;
2164 public override object this[int index]
2166 get
2168 lock (m_SyncRoot)
2170 return m_InnerList[index];
2174 set
2176 lock (m_SyncRoot)
2178 m_InnerList[index] = value;
2183 public override int Add(object value)
2185 lock (m_SyncRoot)
2187 return m_InnerList.Add(value);
2191 public override void Clear()
2193 lock (m_SyncRoot)
2195 m_InnerList.Clear();
2199 public override bool Contains(object value)
2201 lock (m_SyncRoot)
2203 return m_InnerList.Contains(value);
2207 public override int IndexOf(object value)
2209 lock (m_SyncRoot)
2211 return m_InnerList.IndexOf(value);
2215 public override void Insert(int index, object value)
2217 lock (m_SyncRoot)
2219 m_InnerList.Insert(index, value);
2223 public override void Remove(object value)
2225 lock (m_SyncRoot)
2227 m_InnerList.Remove(value);
2231 public override void RemoveAt(int index)
2233 lock (m_SyncRoot)
2235 m_InnerList.RemoveAt(index);
2239 public override void CopyTo(Array array, int index)
2241 lock (m_SyncRoot)
2243 m_InnerList.CopyTo(array, index);
2247 public override IEnumerator GetEnumerator()
2249 lock (m_SyncRoot)
2251 return m_InnerList.GetEnumerator();
2256 #endregion
2258 #region FixedSizeListWrapper
2260 [Serializable]
2261 private class FixedSizeListWrapper
2262 : ListWrapper
2264 protected virtual string ErrorMessage
2266 get
2268 return "List is fixed-size.";
2272 public override bool IsFixedSize
2274 get
2276 return true;
2280 public FixedSizeListWrapper(IList innerList)
2281 : base(innerList)
2285 public override int Add(object value)
2287 throw new NotSupportedException(this.ErrorMessage);
2290 public override void Clear()
2292 throw new NotSupportedException(this.ErrorMessage);
2295 public override void Insert(int index, object value)
2297 throw new NotSupportedException(this.ErrorMessage);
2300 public override void Remove(object value)
2302 throw new NotSupportedException(this.ErrorMessage);
2305 public override void RemoveAt(int index)
2307 throw new NotSupportedException(this.ErrorMessage);
2311 #endregion
2313 #region ReadOnlyListWrapper
2315 [Serializable]
2316 private sealed class ReadOnlyListWrapper
2317 : FixedSizeListWrapper
2319 protected override string ErrorMessage
2321 get
2323 return "List is read-only.";
2327 public override bool IsReadOnly
2329 get
2331 return true;
2335 public ReadOnlyListWrapper(IList innerList)
2336 : base(innerList)
2340 public override object this[int index]
2342 get
2344 return m_InnerList[index];
2347 set
2349 throw new NotSupportedException(this.ErrorMessage);
2354 #endregion
2356 #region ListWrapper
2358 /// <summary>
2359 /// Decorates/Wraps any <c>IList</c> implementing object.
2360 /// </summary>
2361 [Serializable]
2362 private class ListWrapper
2363 : IList
2365 #region Fields
2367 protected IList m_InnerList;
2369 #endregion
2371 #region Constructors
2373 public ListWrapper(IList innerList)
2375 m_InnerList = innerList;
2378 #endregion
2380 #region Indexers
2382 public virtual object this[int index]
2384 get
2386 return m_InnerList[index];
2389 set
2391 m_InnerList[index] = value;
2395 #endregion
2397 #region Properties
2399 public virtual int Count
2401 get
2403 return m_InnerList.Count;
2407 public virtual bool IsSynchronized
2409 get
2411 return m_InnerList.IsSynchronized;
2415 public virtual object SyncRoot
2417 get
2419 return m_InnerList.SyncRoot;
2423 public virtual bool IsFixedSize
2425 get
2427 return m_InnerList.IsFixedSize;
2431 public virtual bool IsReadOnly
2433 get
2435 return m_InnerList.IsReadOnly;
2439 #endregion
2441 #region Methods
2443 public virtual int Add(object value)
2445 return m_InnerList.Add(value);
2448 public virtual void Clear()
2450 m_InnerList.Clear();
2453 public virtual bool Contains(object value)
2455 return m_InnerList.Contains(value);
2458 public virtual int IndexOf(object value)
2460 return m_InnerList.IndexOf(value);
2463 public virtual void Insert(int index, object value)
2465 m_InnerList.Insert(index, value);
2468 public virtual void Remove(object value)
2470 m_InnerList.Remove(value);
2473 public virtual void RemoveAt(int index)
2475 m_InnerList.RemoveAt(index);
2478 public virtual void CopyTo(Array array, int index)
2480 m_InnerList.CopyTo(array, index);
2483 public virtual IEnumerator GetEnumerator()
2485 return m_InnerList.GetEnumerator();
2488 #endregion
2491 #endregion
2494 // Start of ArrayList
2497 #region Fields
2499 private const int DefaultInitialCapacity = 4;
2501 /// <summary>
2502 /// Number of items in the list.
2503 /// </summary>
2504 private int _size;
2506 /// <summary>
2507 /// Array to store the items.
2508 /// </summary>
2509 private object[] _items;
2511 /// <summary>
2512 /// Total number of state changes.
2513 /// </summary>
2514 private int _version;
2516 private static readonly object [] EmptyArray = new object [0];
2518 #endregion
2520 #region Constructors
2522 /// <summary>
2523 /// Initializes a new instance of the <see cref="ArrayList"/> class that is empty and
2524 /// has the default initial capacity (16).
2525 /// </summary>
2526 public ArrayList()
2528 _items = EmptyArray;
2531 /// <summary>
2532 /// Initializes a new instance of the <see cref="ArrayList"/> class that contains
2533 /// elements copied from the specified collection and that has the same initial capacity
2534 /// as the number of elements copied.
2535 /// </summary>
2536 /// <param name="c">
2537 /// The <see cref="ICollection"/> whose elements are copied into the new list.
2538 /// </param>
2539 /// <exception cref="ArgumentNullException">
2540 /// The argument <c>c</c> is a null reference.
2541 /// </exception>
2542 public ArrayList(ICollection c)
2544 Array array;
2546 if (c == null)
2548 throw new ArgumentNullException("c");
2551 array = c as Array;
2553 if (array != null && array.Rank != 1)
2555 throw new RankException();
2558 _items = new object[c.Count];
2560 AddRange(c);
2563 /// <summary>
2564 /// Initializes a new instance of the <see cref="ArrayList"/> class that is empty and
2565 /// has the specified initial capacity.
2566 /// </summary>
2567 /// <param name="capacity">
2568 /// The number of elements that hte new list is initially capable of storing.
2569 /// </param>
2570 /// <exception cref="ArgumentOutOfRangeException">
2571 /// The <c>capacity</c> is less than zero.
2572 /// </exception>
2573 public ArrayList(int capacity)
2575 if (capacity < 0)
2577 ThrowNewArgumentOutOfRangeException ("capacity",
2578 capacity, "The initial capacity can't be smaller than zero.");
2581 if (capacity == 0)
2583 capacity = DefaultInitialCapacity;
2585 _items = new object [capacity];
2588 /// <summary>
2589 /// Used by ArrayListAdapter to allow creation of an ArrayList with no storage buffer.
2590 /// </summary>
2591 private ArrayList(int initialCapacity, bool forceZeroSize)
2593 if (forceZeroSize)
2595 _items = null;
2597 else
2599 throw new InvalidOperationException("Use ArrayList(int)");
2603 /// <summary>
2604 /// Initializes a new array list that contains a copy of the given array and with the
2605 /// given count.
2606 /// </summary>
2607 /// <param name="array"></param>
2608 private ArrayList(object[] array, int index, int count)
2610 if (count == 0)
2612 _items = new object[DefaultInitialCapacity];
2614 else
2616 _items = new object[count];
2619 Array.Copy(array, index, _items, 0, count);
2621 _size = count;
2624 #endregion
2626 #region Indexers
2628 /// <summary>
2629 /// Gets/Sets an element in the list by index.
2630 /// </summary>
2631 /// <exception cref="ArgumentOutOfRangeException">
2632 /// The index is less than 0 or more then or equal to the list count.
2633 /// </exception>
2634 public virtual object this[int index]
2636 get
2638 if (index < 0 || index >= _size)
2640 ThrowNewArgumentOutOfRangeException ("index", index,
2641 "Index is less than 0 or more than or equal to the list count.");
2644 return _items[index];
2647 set
2649 if (index < 0 || index >= _size)
2651 ThrowNewArgumentOutOfRangeException ("index", index,
2652 "Index is less than 0 or more than or equal to the list count.");
2655 _items[index] = value;
2656 _version++;
2660 #endregion
2662 #region Properties
2664 /// <summary>
2665 /// Gets the number of elements in the list.
2666 /// </summary>
2667 public virtual int Count
2669 get
2671 return _size;
2675 /// <summary>
2676 /// Gets the number of elements the list can carry without needing to expand.
2677 /// </summary>
2678 /// <remarks>
2679 /// ArrayLists automatically double their capacity when the capacity limit is broken.
2680 /// </remarks>
2681 /// <exception cref="ArgumentOutOfRangeException">
2682 /// The capacity is less than the count.
2683 /// </exception>
2684 public virtual int Capacity
2686 get
2688 return _items.Length;
2691 set
2693 if (value < _size)
2695 ThrowNewArgumentOutOfRangeException ("Capacity", value,
2696 "Must be more than count.");
2699 object[] newArray;
2701 newArray = new object[value];
2703 Array.Copy(_items, 0, newArray, 0, _size);
2705 _items = newArray;
2709 /// <summary>
2710 /// <see cref="IList.IsFixedSize"/>
2711 /// </summary>
2712 /// <remarks/>
2713 public virtual bool IsFixedSize
2715 get
2717 return false;
2721 /// <summary>
2722 /// <see cref="IList.IsReadOnly"/>
2723 /// </summary>
2724 public virtual bool IsReadOnly
2726 get
2728 return false;
2732 /// <summary>
2733 /// <see cref="ICollection.IsSynchronized"/>
2734 /// </summary>
2735 public virtual bool IsSynchronized
2737 get
2739 return false;
2743 /// <summary>
2744 /// <see cref="ICollection.SyncRoot"/>
2745 /// </summary>
2746 public virtual object SyncRoot
2748 get
2750 return this;
2754 #endregion
2756 #region Methods
2758 /// <remarks>
2759 /// Ensures that the list has the capacity to contain the given <c>count</c> by
2760 /// automatically expanding the capacity when required.
2761 /// </remarks>
2762 private void EnsureCapacity(int count)
2764 if (count <= _items.Length)
2766 return;
2769 int newLength;
2770 object[] newData;
2772 newLength = _items.Length << 1;
2773 if (newLength == 0)
2774 newLength = DefaultInitialCapacity;
2776 while (newLength < count)
2778 newLength <<= 1;
2781 newData = new object[newLength];
2783 Array.Copy(_items, 0, newData, 0, _items.Length);
2785 _items = newData;
2788 /// <summary>
2789 /// Shifts a section of the list.
2790 /// </summary>
2791 /// <param name="index">
2792 /// The start of the section to shift (the element at index is included in the shift).
2793 /// </param>
2794 /// <param name="count">
2795 /// The number of positions to shift by (can be negative).
2796 /// </param>
2797 private void Shift(int index, int count)
2799 if (count > 0)
2801 if (_size + count > _items.Length)
2803 int newLength;
2804 object[] newData;
2806 newLength = (_items.Length > 0) ? _items.Length << 1 : 1;
2808 while (newLength < _size + count)
2810 newLength <<= 1;
2813 newData = new object[newLength];
2815 Array.Copy(_items, 0, newData, 0, index);
2816 Array.Copy(_items, index, newData, index + count, _size - index);
2818 _items = newData;
2820 else
2822 Array.Copy(_items, index, _items, index + count, _size - index);
2825 else if (count < 0)
2827 // Remember count is negative so this is actually index + (-count)
2829 int x = index - count ;
2831 Array.Copy(_items, x, _items, index, _size - x);
2832 Array.Clear(_items, _size + count, - count);
2836 public virtual int Add(object value)
2838 // Do a check here in case EnsureCapacity isn't inlined.
2840 if (_items.Length <= _size /* same as _items.Length < _size + 1) */)
2842 EnsureCapacity(_size + 1);
2845 _items[_size] = value;
2847 _version++;
2849 return _size++;
2852 public virtual void Clear()
2854 // Keep the array but null all members so they can be garbage collected.
2856 Array.Clear(_items, 0, _size);
2858 _size = 0;
2859 _version++;
2862 public virtual bool Contains(object item)
2864 return IndexOf(item, 0, _size) > -1;
2867 internal virtual bool Contains(object value, int startIndex, int count)
2869 return IndexOf(value, startIndex, count) > -1;
2872 public virtual int IndexOf(object value)
2874 return IndexOf(value, 0);
2877 public virtual int IndexOf(object value, int startIndex)
2879 return IndexOf(value, startIndex, _size - startIndex);
2882 public virtual int IndexOf(object value, int startIndex, int count)
2884 if (startIndex < 0 || startIndex > _size)
2886 ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
2887 "Does not specify valid index.");
2890 if (count < 0)
2892 ThrowNewArgumentOutOfRangeException ("count", count,
2893 "Can't be less than 0.");
2896 // re-ordered to avoid integer overflow
2897 if (startIndex > _size - count)
2899 // LAMESPEC: Every other method throws ArgumentException
2901 throw new ArgumentOutOfRangeException("count",
2902 "Start index and count do not specify a valid range.");
2905 return Array.IndexOf(_items, value, startIndex, count);
2908 public virtual int LastIndexOf(object value)
2910 return LastIndexOf(value, _size - 1);
2913 public virtual int LastIndexOf(object value, int startIndex)
2915 return LastIndexOf(value, startIndex, startIndex + 1);
2918 public virtual int LastIndexOf (object value, int startIndex, int count)
2920 // Array will catch the exceptions
2921 return Array.LastIndexOf (_items, value, startIndex, count);
2924 public virtual void Insert(int index, object value)
2926 if (index < 0 || index > _size)
2928 ThrowNewArgumentOutOfRangeException ("index", index,
2929 "Index must be >= 0 and <= Count.");
2932 Shift(index, 1);
2934 _items[index] = value;
2935 _size++;
2936 _version++;
2939 public virtual void InsertRange(int index, ICollection c)
2941 int i;
2943 if (c == null)
2945 throw new ArgumentNullException("c");
2948 if (index < 0 || index > _size)
2950 ThrowNewArgumentOutOfRangeException ("index", index,
2951 "Index must be >= 0 and <= Count.");
2954 i = c.Count;
2956 // Do a check here in case EnsureCapacity isn't inlined.
2958 if (_items.Length < _size + i)
2960 EnsureCapacity(_size + i);
2963 if (index < _size)
2965 Array.Copy(_items, index, _items, index + i, _size - index);
2968 // Handle inserting a range from a list to itself specially.
2970 if (this == c.SyncRoot)
2972 // Copy range before the insert point.
2974 Array.Copy(_items, 0, _items, index, index);
2976 // Copy range after the insert point.
2978 Array.Copy(_items, index + i, _items, index << 1, _size - index);
2980 else
2982 c.CopyTo(_items, index);
2985 _size += c.Count;
2986 _version++;
2989 public virtual void Remove(object obj)
2991 int x;
2993 x = IndexOf(obj);
2995 if (x > -1)
2997 RemoveAt(x);
3000 _version++;
3003 public virtual void RemoveAt(int index)
3005 if (index < 0 || index >= _size)
3007 ThrowNewArgumentOutOfRangeException ("index", index,
3008 "Less than 0 or more than list count.");
3011 Shift(index, -1);
3012 _size--;
3013 _version++;
3016 public virtual void RemoveRange(int index, int count)
3018 ArrayList.CheckRange(index, count, _size);
3020 Shift(index, -count);
3021 _size -= count;
3022 _version++;
3025 public virtual void Reverse()
3027 Array.Reverse(_items, 0, _size);
3028 _version++;
3031 public virtual void Reverse(int index, int count)
3033 ArrayList.CheckRange(index, count, _size);
3035 Array.Reverse(_items, index, count);
3036 _version++;
3039 public virtual void CopyTo(System.Array array)
3041 Array.Copy(_items, array, _size);
3044 public virtual void CopyTo(System.Array array, int arrayIndex)
3046 CopyTo(0, array, arrayIndex, _size);
3049 public virtual void CopyTo(int index, System.Array array, int arrayIndex, int count)
3051 if (array == null)
3053 throw new ArgumentNullException("array");
3056 if (array.Rank != 1)
3058 // LAMESPEC:
3059 // This should be a RankException because Array.Copy throws RankException.
3061 throw new ArgumentException("Must have only 1 dimensions.", "array");
3064 Array.Copy(_items, index, array, arrayIndex, count);
3067 public virtual IEnumerator GetEnumerator()
3069 return new SimpleEnumerator(this);
3072 public virtual IEnumerator GetEnumerator(int index, int count)
3074 ArrayList.CheckRange(index, count, _size);
3076 return new ArrayListEnumerator(this, index, count);
3079 public virtual void AddRange(ICollection c)
3081 InsertRange(_size, c);
3084 public virtual int BinarySearch(object value)
3086 try
3088 return Array.BinarySearch(_items, 0, _size, value);
3090 catch (InvalidOperationException e)
3092 throw new ArgumentException(e.Message);
3096 public virtual int BinarySearch(object value, IComparer comparer)
3098 try
3100 return Array.BinarySearch(_items, 0, _size, value, comparer);
3102 catch (InvalidOperationException e)
3104 throw new ArgumentException(e.Message);
3108 public virtual int BinarySearch(int index, int count, object value, IComparer comparer)
3110 try
3112 return Array.BinarySearch(_items, index, count, value, comparer);
3114 catch (InvalidOperationException e)
3116 throw new ArgumentException(e.Message);
3119 public virtual ArrayList GetRange(int index, int count)
3121 ArrayList.CheckRange(index, count, _size);
3123 if (this.IsSynchronized)
3125 return ArrayList.Synchronized(new RangedArrayList(this, index, count));
3127 else
3129 return new RangedArrayList(this, index, count);
3133 public virtual void SetRange(int index, ICollection c)
3135 if (c == null)
3137 throw new ArgumentNullException("c");
3140 if (index < 0 || index + c.Count > _size)
3142 throw new ArgumentOutOfRangeException("index");
3145 c.CopyTo(_items, index);
3147 _version++;
3150 public virtual void TrimToSize()
3152 if (_items.Length > _size)
3154 object[] newArray;
3156 if (_size == 0)
3158 newArray = new object[DefaultInitialCapacity];
3160 else
3162 newArray = new object[_size];
3165 Array.Copy(_items, 0, newArray, 0, _size);
3167 _items = newArray;
3171 public virtual void Sort()
3173 Array.Sort(_items, 0, _size);
3175 _version++;
3178 public virtual void Sort(IComparer comparer)
3180 Array.Sort(_items, 0, _size, comparer);
3183 public virtual void Sort(int index, int count, IComparer comparer)
3185 ArrayList.CheckRange(index, count, _size);
3187 Array.Sort(_items, index, count, comparer);
3190 public virtual object[] ToArray()
3192 object[] retval;
3194 retval = new object[_size];
3196 CopyTo(retval);
3198 return retval;
3201 public virtual Array ToArray(Type type)
3203 Array retval;
3205 retval = Array.CreateInstance(type, _size);
3207 CopyTo(retval);
3209 return retval;
3212 public virtual object Clone()
3214 return new ArrayList(this._items, 0, this._size);
3217 #endregion
3219 #region Static Methods
3221 /// <summary>
3222 /// Does a check of the arguments many of the methods in ArrayList use.
3223 /// </summary>
3224 /// <remarks>
3225 /// The choice of exceptions thrown sometimes seem to be arbitrarily chosen so
3226 /// not all methods actually make use of CheckRange.
3227 /// </remarks>
3228 internal static void CheckRange(int index, int count, int listCount)
3230 if (index < 0)
3232 ThrowNewArgumentOutOfRangeException ("index", index, "Can't be less than 0.");
3235 if (count < 0)
3237 ThrowNewArgumentOutOfRangeException ("count", count, "Can't be less than 0.");
3240 // re-ordered to avoid possible integer overflow
3241 if (index > listCount - count)
3243 throw new ArgumentException("Index and count do not denote a valid range of elements.", "index");
3247 internal static void ThrowNewArgumentOutOfRangeException (string name, object actual, string message)
3249 throw new ArgumentOutOfRangeException (
3250 #if !INSIDE_CORLIB && NET_2_1
3251 name, message
3252 #else
3253 name, actual, message
3254 #endif
3258 public static ArrayList Adapter(IList list)
3260 // LAMESPEC: EWWW. Other lists aren't *Array*Lists.
3262 if (list == null)
3264 throw new ArgumentNullException("list");
3267 ArrayList arrayList = list as ArrayList;
3268 if (arrayList != null)
3269 return arrayList;
3270 else
3271 arrayList = new ArrayListAdapter(list);
3273 if (list.IsSynchronized)
3274 return ArrayList.Synchronized(arrayList);
3275 else
3276 return arrayList;
3279 public static ArrayList Synchronized(ArrayList list)
3281 if (list == null)
3283 throw new ArgumentNullException("list");
3286 if (list.IsSynchronized)
3288 return list;
3291 return new SynchronizedArrayListWrapper(list);
3294 public static IList Synchronized(IList list)
3296 if (list == null)
3298 throw new ArgumentNullException("list");
3301 if (list.IsSynchronized)
3303 return list;
3306 return new SynchronizedListWrapper(list);
3309 public static ArrayList ReadOnly(ArrayList list)
3311 if (list == null)
3313 throw new ArgumentNullException("list");
3316 if (list.IsReadOnly)
3318 return list;
3321 return new ReadOnlyArrayListWrapper(list);
3324 public static IList ReadOnly(IList list)
3326 if (list == null)
3328 throw new ArgumentNullException("list");
3331 if (list.IsReadOnly)
3333 return list;
3336 return new ReadOnlyListWrapper(list);
3339 public static ArrayList FixedSize(ArrayList list)
3341 if (list == null)
3343 throw new ArgumentNullException("list");
3346 if (list.IsFixedSize)
3348 return list;
3351 return new FixedSizeArrayListWrapper(list);
3354 public static IList FixedSize(IList list)
3356 if (list == null)
3358 throw new ArgumentNullException("list");
3361 if (list.IsFixedSize)
3363 return list;
3366 return new FixedSizeListWrapper(list);
3369 public static ArrayList Repeat(object value, int count)
3371 ArrayList arrayList = new ArrayList(count);
3373 for (int i = 0; i < count; i++)
3375 arrayList.Add(value);
3378 return arrayList;
3381 #endregion