// Implementation of the ECMA ArrayList.
//
// Copyright (c) 2003 Thong (Tum) Nguyen [tum@veridicus.com]
-//
-// http://www.opensource.org/licenses/mit-license.html
-//
-// 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.
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 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
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
-using System.Collections;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
namespace System.Collections
{
[Serializable]
- public class ArrayList
- : IList, ICloneable, ICollection, IEnumerable
- {
+#if INSIDE_CORLIB
+ [ComVisible(true)]
+ [DebuggerDisplay ("Count={Count}")]
+ [DebuggerTypeProxy (typeof (CollectionDebuggerView))]
+ public class ArrayList : IList, ICloneable, ICollection, IEnumerable {
+#else
+ internal class ArrayList : IList {
+#endif
#region Enumerator
private sealed class ArrayListEnumerator
: IEnumerator, ICloneable
{
+ private object m_Current;
+ private ArrayList m_List;
private int m_Pos;
private int m_Index;
private int m_Count;
- private object m_Current;
- private ArrayList m_List;
private int m_ExpectedStateChanges;
public ArrayListEnumerator(ArrayList list)
sealed class SimpleEnumerator : IEnumerator, ICloneable
{
ArrayList list;
+ object currentElement;
int index;
int version;
- object currentElement;
static object endFlag = new object ();
public SimpleEnumerator (ArrayList list)
{
if (startIndex < 0 || startIndex > m_Adaptee.Count)
{
- throw new ArgumentOutOfRangeException("startIndex", startIndex,
+ ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
"Does not specify valid index.");
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", count,
+ ThrowNewArgumentOutOfRangeException ("count", count,
"Can't be less than 0.");
}
{
if (startIndex < 0)
{
- throw new ArgumentOutOfRangeException("startIndex", startIndex, "< 0");
+ ThrowNewArgumentOutOfRangeException ("startIndex", startIndex, "< 0");
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", count, "count is negative.");
+ ThrowNewArgumentOutOfRangeException ("count", count, "count is negative.");
}
if (startIndex - count + 1 < 0)
{
- throw new ArgumentOutOfRangeException("count", count, "count is too large.");
+ ThrowNewArgumentOutOfRangeException ("count", count, "count is too large.");
}
if (value == null)
if (index > m_Adaptee.Count)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index must be >= 0 and <= Count.");
}
{
if (index < 0)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Can't be less than zero.");
}
if (arrayIndex < 0)
{
- throw new ArgumentOutOfRangeException("arrayIndex", arrayIndex,
+ ThrowNewArgumentOutOfRangeException ("arrayIndex", arrayIndex,
"Can't be less than zero.");
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Can't be less than zero.");
}
while (x <= y)
{
- z = (x + y) / 2;
+ // Be careful with overflows
+ z = x + ((y - x) / 2);
r = comparer.Compare(value, m_Adaptee[z]);
// Pick the pivot using the median-of-three strategy.
- middle = (left + right) / 2;
+ // Be careful with overflows
+ middle = left + ((right - left) / 2);
if (comparer.Compare(list[middle], list[left]) < 0)
{
{
if (startIndex < 0 || startIndex > m_InnerCount)
{
- throw new ArgumentOutOfRangeException("startIndex", startIndex,
+ ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
"Does not specify valid index.");
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", count,
+ ThrowNewArgumentOutOfRangeException ("count", count,
"Can't be less than 0.");
}
{
if (startIndex < 0)
{
- throw new ArgumentOutOfRangeException("startIndex", startIndex, "< 0");
+ ThrowNewArgumentOutOfRangeException ("startIndex", startIndex, "< 0");
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", count, "count is negative.");
+ ThrowNewArgumentOutOfRangeException ("count", count, "count is negative.");
}
int retval = m_InnerArrayList.LastIndexOf(value, m_InnerIndex + startIndex, count);
if (index < 0 || index > m_InnerCount)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index must be >= 0 and <= Count.");
}
if (index < 0 || index > m_InnerCount)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index must be >= 0 and <= Count.");
}
if (index < 0 || index > m_InnerCount)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index must be >= 0 and <= Count.");
}
if (index < 0 || index > m_InnerCount)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index must be >= 0 and <= Count.");
}
array = new object[m_InnerCount];
- m_InnerArrayList.CopyTo(0, array, 0, m_InnerCount);
+ m_InnerArrayList.CopyTo (m_InnerIndex, array, 0, m_InnerCount);
return array;
}
array = Array.CreateInstance(elementType, m_InnerCount);
- m_InnerArrayList.CopyTo(0, array, 0, m_InnerCount);
+ m_InnerArrayList.CopyTo(m_InnerIndex, array, 0, m_InnerCount);
return array;
}
#region Fields
- private const int DefaultInitialCapacity = 0x10;
-
- /// <summary>
- /// Number of items in the list.
- /// </summary>
- private int _size;
+ private const int DefaultInitialCapacity = 4;
/// <summary>
/// Array to store the items.
/// </summary>
private object[] _items;
-
+
+ /// <summary>
+ /// Number of items in the list.
+ /// </summary>
+ private int _size;
+
/// <summary>
/// Total number of state changes.
/// </summary>
private int _version;
+ private static readonly object [] EmptyArray = new object [0];
+
#endregion
#region Constructors
/// </summary>
public ArrayList()
{
- _items = new object[DefaultInitialCapacity];
+ _items = EmptyArray;
}
/// <summary>
/// Initializes a new instance of the <see cref="ArrayList"/> class that is empty and
/// has the specified initial capacity.
/// </summary>
- /// <param name="initialCapacity">
+ /// <param name="capacity">
/// The number of elements that hte new list is initially capable of storing.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// The <c>capacity</c> is less than zero.
/// </exception>
- public ArrayList(int initialCapacity)
+ public ArrayList(int capacity)
{
- if (initialCapacity < 0)
+ if (capacity < 0)
{
- throw new ArgumentOutOfRangeException("initialCapacity",
- initialCapacity, "The initial capacity can't be smaller than zero.");
+ ThrowNewArgumentOutOfRangeException ("capacity",
+ capacity, "The initial capacity can't be smaller than zero.");
}
- if (initialCapacity == 0)
+ if (capacity == 0)
{
- initialCapacity = DefaultInitialCapacity;
+ capacity = DefaultInitialCapacity;
}
- _items = new object[initialCapacity];
+ _items = new object [capacity];
}
/// <summary>
{
if (index < 0 || index >= _size)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index is less than 0 or more than or equal to the list count.");
}
{
if (index < 0 || index >= _size)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index is less than 0 or more than or equal to the list count.");
}
{
if (value < _size)
{
- throw new ArgumentOutOfRangeException("Capacity", value,
+ ThrowNewArgumentOutOfRangeException ("Capacity", value,
"Must be more than count.");
}
int x = index - count ;
Array.Copy(_items, x, _items, index, _size - x);
+ Array.Clear(_items, _size + count, - count);
}
}
_version++;
}
- public virtual bool Contains(object value)
+ public virtual bool Contains(object item)
{
- return IndexOf(value, 0, _size) > -1;
+ return IndexOf(item, 0, _size) > -1;
}
internal virtual bool Contains(object value, int startIndex, int count)
{
if (startIndex < 0 || startIndex > _size)
{
- throw new ArgumentOutOfRangeException("startIndex", startIndex,
+ ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
"Does not specify valid index.");
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", count,
+ ThrowNewArgumentOutOfRangeException ("count", count,
"Can't be less than 0.");
}
{
if (index < 0 || index > _size)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index must be >= 0 and <= Count.");
}
if (index < 0 || index > _size)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Index must be >= 0 and <= Count.");
}
_version++;
}
- public virtual void Remove(object value)
+ public virtual void Remove(object obj)
{
int x;
- x = IndexOf(value);
+ x = IndexOf(obj);
if (x > -1)
{
{
if (index < 0 || index >= _size)
{
- throw new ArgumentOutOfRangeException("index", index,
+ ThrowNewArgumentOutOfRangeException ("index", index,
"Less than 0 or more than list count.");
}
Array.Copy(_items, array, _size);
}
- public virtual void CopyTo(System.Array array, int index)
+ public virtual void CopyTo(System.Array array, int arrayIndex)
{
- CopyTo(0, array, index, _size);
+ CopyTo(0, array, arrayIndex, _size);
}
public virtual void CopyTo(int index, System.Array array, int arrayIndex, int count)
return retval;
}
- public virtual Array ToArray(Type elementType)
+ public virtual Array ToArray(Type type)
{
Array retval;
- retval = Array.CreateInstance(elementType, _size);
+ retval = Array.CreateInstance(type, _size);
CopyTo(retval);
{
if (index < 0)
{
- throw new ArgumentOutOfRangeException("index", index, "Can't be less than 0.");
+ ThrowNewArgumentOutOfRangeException ("index", index, "Can't be less than 0.");
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", count, "Can't be less than 0.");
+ ThrowNewArgumentOutOfRangeException ("count", count, "Can't be less than 0.");
}
// re-ordered to avoid possible integer overflow
}
}
+ internal static void ThrowNewArgumentOutOfRangeException (string name, object actual, string message)
+ {
+ throw new ArgumentOutOfRangeException (
+#if !INSIDE_CORLIB && NET_2_1
+ name, message
+#else
+ name, actual, message
+#endif
+ );
+ }
+
public static ArrayList Adapter(IList list)
{
// LAMESPEC: EWWW. Other lists aren't *Array*Lists.
throw new ArgumentNullException("list");
}
- if (list.IsSynchronized)
- {
- return ArrayList.Synchronized(new ArrayListAdapter(list));
- }
+ ArrayList arrayList = list as ArrayList;
+ if (arrayList != null)
+ return arrayList;
+ else
+ arrayList = new ArrayListAdapter(list);
+
+ if (list.IsSynchronized)
+ return ArrayList.Synchronized(arrayList);
else
- {
- return new ArrayListAdapter(list);
- }
+ return arrayList;
}
- public static ArrayList Synchronized(ArrayList arrayList)
+ public static ArrayList Synchronized(ArrayList list)
{
- if (arrayList == null)
+ if (list == null)
{
- throw new ArgumentNullException("arrayList");
+ throw new ArgumentNullException("list");
}
- if (arrayList.IsSynchronized)
+ if (list.IsSynchronized)
{
- return arrayList;
+ return list;
}
- return new SynchronizedArrayListWrapper(arrayList);
+ return new SynchronizedArrayListWrapper(list);
}
public static IList Synchronized(IList list)
return new SynchronizedListWrapper(list);
}
- public static ArrayList ReadOnly(ArrayList arrayList)
+ public static ArrayList ReadOnly(ArrayList list)
{
- if (arrayList == null)
+ if (list == null)
{
- throw new ArgumentNullException("arrayList");
+ throw new ArgumentNullException("list");
}
- if (arrayList.IsReadOnly)
+ if (list.IsReadOnly)
{
- return arrayList;
+ return list;
}
- return new ReadOnlyArrayListWrapper(arrayList);
+ return new ReadOnlyArrayListWrapper(list);
}
public static IList ReadOnly(IList list)
return new ReadOnlyListWrapper(list);
}
- public static ArrayList FixedSize(ArrayList arrayList)
+ public static ArrayList FixedSize(ArrayList list)
{
- if (arrayList == null)
+ if (list == null)
{
- throw new ArgumentNullException("arrayList");
+ throw new ArgumentNullException("list");
}
- if (arrayList.IsFixedSize)
+ if (list.IsFixedSize)
{
- return arrayList;
+ return list;
}
- return new FixedSizeArrayListWrapper(arrayList);
+ return new FixedSizeArrayListWrapper(list);
}
public static IList FixedSize(IList list)