// Gonzalo Paniagua Javier (gonzalo@ximian.com)
//
// (C) 2001-2003 Ximian, Inc. http://www.ximian.com
-//
-
-//
-// 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
using System.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+
#if NET_2_0
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Runtime.ConstrainedExecution;
#endif
+
namespace System
{
-
[Serializable]
- [MonoTODO ("We are doing way to many double/triple exception checks for the overloaded functions")]
- [MonoTODO ("Sort overloads parameter checks are VERY inconsistent")]
+#if NET_2_0
+ [ComVisible (true)]
+#endif
+ // FIXME: We are doing way to many double/triple exception checks for the overloaded functions"
+ // FIXME: Sort overloads parameter checks are VERY inconsistent"
public abstract class Array : ICloneable, ICollection, IList, IEnumerable
{
// Constructor
{
}
+#if NET_2_0
+ // FIXME: they should not be exposed, but there are some
+ // dependent code in the runtime.
+ protected int InternalArray__ICollection_get_Count<T> ()
+ {
+ return Length;
+ }
+
+ protected IEnumerator<T> InternalArray__IEnumerable_GetEnumerator<T> ()
+ {
+ return new InternalEnumerator<T> (this);
+ }
+
+ protected void InternalArray__ICollection_Clear<T> ()
+ {
+ throw new NotSupportedException ("Collection is read-only");
+ }
+
+ protected void InternalArray__ICollection_Add<T> (T item)
+ {
+ throw new NotSupportedException ("Collection is read-only");
+ }
+
+ protected bool InternalArray__ICollection_Remove<T> (T item)
+ {
+ throw new NotSupportedException ("Collection is read-only");
+ }
+
+ protected bool InternalArray__ICollection_Contains<T> (T item)
+ {
+ if (this.Rank > 1)
+ throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
+
+ int length = this.Length;
+ for (int i = 0; i < length; i++) {
+ T value;
+ GetGenericValueImpl (i, out value);
+ if (item == null){
+ if (value == null)
+ return true;
+ else
+ return false;
+ }
+
+ if (item.Equals (value))
+ return true;
+ }
+
+ return false;
+ }
+
+ protected void InternalArray__ICollection_CopyTo<T> (T[] array, int index)
+ {
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ // The order of these exception checks may look strange,
+ // but that's how the microsoft runtime does it.
+ if (this.Rank > 1)
+ throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
+ if (index + this.GetLength (0) > array.GetLowerBound (0) + array.GetLength (0))
+ throw new ArgumentException ("Destination array was not long " +
+ "enough. Check destIndex and length, and the array's " +
+ "lower bounds.");
+ if (array.Rank > 1)
+ throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
+ if (index < 0)
+ throw new ArgumentOutOfRangeException (
+ "index", Locale.GetText ("Value has to be >= 0."));
+
+ Copy (this, this.GetLowerBound (0), array, index, this.GetLength (0));
+ }
+
+ protected void InternalArray__Insert<T> (int index, T item)
+ {
+ throw new NotSupportedException ("Collection is read-only");
+ }
+
+ protected void InternalArray__RemoveAt<T> (int index)
+ {
+ throw new NotSupportedException ("Collection is read-only");
+ }
+
+ protected int InternalArray__IndexOf<T> (T item)
+ {
+ if (this.Rank > 1)
+ throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
+
+ int length = this.Length;
+ for (int i = 0; i < length; i++) {
+ T value;
+ GetGenericValueImpl (i, out value);
+ if (item == null){
+ if (value == null)
+ return i + this.GetLowerBound (0);
+ else {
+ unchecked {
+ return this.GetLowerBound (0) - 1;
+ }
+ }
+ }
+ if (item.Equals (value))
+ // array index may not be zero-based.
+ // use lower bound
+ return i + this.GetLowerBound (0);
+ }
+
+ int retVal;
+ unchecked {
+ // lower bound may be MinValue
+ retVal = this.GetLowerBound (0) - 1;
+ }
+
+ return retVal;
+ }
+
+ protected T InternalArray__get_Item<T> (int index)
+ {
+ if (unchecked ((uint) index) >= unchecked ((uint) Length))
+ throw new ArgumentOutOfRangeException ("index");
+
+ T value;
+ GetGenericValueImpl (index, out value);
+ return value;
+ }
+
+ protected void InternalArray__set_Item<T> (int index, T item)
+ {
+ if (unchecked ((uint) index) >= unchecked ((uint) Length))
+ throw new ArgumentOutOfRangeException ("index");
+
+ SetGenericValueImpl (index, ref item);
+ }
+
+ // CAUTION! No bounds checking!
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern void GetGenericValueImpl<T> (int pos, out T value);
+
+ // CAUTION! No bounds checking!
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern void SetGenericValueImpl<T> (int pos, ref T value);
+
+ internal struct InternalEnumerator<T> : IEnumerator<T>
+ {
+ const int NOT_STARTED = -2;
+
+ // this MUST be -1, because we depend on it in move next.
+ // we just decr the size, so, 0 - 1 == FINISHED
+ const int FINISHED = -1;
+
+ Array array;
+ int idx;
+
+ internal InternalEnumerator (Array array)
+ {
+ this.array = array;
+ idx = NOT_STARTED;
+ }
+
+ public void Dispose ()
+ {
+ idx = NOT_STARTED;
+ }
+
+ public bool MoveNext ()
+ {
+ if (idx == NOT_STARTED)
+ idx = array.Length;
+
+ return idx != FINISHED && -- idx != FINISHED;
+ }
+
+ public T Current {
+ get {
+ if (idx < 0)
+ throw new InvalidOperationException ();
+
+ return array.InternalArray__get_Item<T> (array.Length - 1 - idx);
+ }
+ }
+
+ void IEnumerator.Reset ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ object IEnumerator.Current {
+ get {
+ return Current;
+ }
+ }
+ }
+#endif
+
// Properties
public int Length {
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.Success)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
#endif
get {
int length = this.GetLength (0);
[ComVisible (false)]
public long LongLength {
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.Success)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
#endif
get { return Length; }
}
public int Rank {
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.Success)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
#endif
get {
return this.GetRank ();
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
int IList.IndexOf (object value)
{
// InternalCall Methods
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- private extern int GetRank ();
+ extern int GetRank ();
[MethodImplAttribute (MethodImplOptions.InternalCall)]
public extern int GetLength (int dimension);
#endif
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.Success)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
#endif
[MethodImplAttribute (MethodImplOptions.InternalCall)]
public extern int GetLowerBound (int dimension);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern object GetValue (int[] indices);
+ public extern object GetValue (params int[] indices);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern void SetValue (object value, int[] indices);
+ public extern void SetValue (object value, params int[] indices);
// CAUTION! No bounds checking!
[MethodImplAttribute (MethodImplOptions.InternalCall)]
}
}
- public virtual bool IsSynchronized {
+ public
+#if !NET_2_0
+ virtual
+#endif
+ bool IsSynchronized {
get {
return false;
}
}
- public virtual object SyncRoot {
+ public
+#if !NET_2_0
+ virtual
+#endif
+ object SyncRoot {
get {
return this;
}
}
- public virtual bool IsFixedSize {
+ public
+#if !NET_2_0
+ virtual
+#endif
+ bool IsFixedSize {
get {
return true;
}
}
- public virtual bool IsReadOnly {
+ public
+#if !NET_2_0
+ virtual
+#endif
+ bool IsReadOnly {
get {
return false;
}
}
- public virtual IEnumerator GetEnumerator ()
+ public
+#if !NET_2_0
+ virtual
+#endif
+ IEnumerator GetEnumerator ()
{
return new SimpleEnumerator (this);
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.Success)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
#endif
public int GetUpperBound (int dimension)
{
}
#endif
-// // This function is currently unused, but just in case we need it later on ... */
-// internal int IndexToPos (int[] idxs)
-// {
-// if (idxs == null)
-// throw new ArgumentNullException ("idxs");
-//
-// if ((idxs.Rank != 1) || (idxs.Length != Rank))
-// throw new ArgumentException ();
-//
-// if ((idxs [0] < GetLowerBound (0)) || (idxs [0] > GetUpperBound (0)))
-// throw new IndexOutOfRangeException();
-//
-// int pos = idxs [0] - GetLowerBound (0);
-// for (int i = 1; i < Rank; i++) {
-// if ((idxs [i] < GetLowerBound (i)) || (idxs [i] > GetUpperBound (i)))
-// throw new IndexOutOfRangeException();
-//
-// pos *= GetLength (i);
-// pos += idxs [i] - GetLowerBound (i);
-// }
-//
-// return pos;
-// }
-
public void SetValue (object value, int index)
{
if (Rank != 1)
public static Array CreateInstance (Type elementType, int length)
{
int[] lengths = {length};
- int[] bounds = null;
- return CreateInstanceImpl (elementType, lengths, bounds);
+ return CreateInstance (elementType, lengths);
}
public static Array CreateInstance (Type elementType, int length1, int length2)
{
int[] lengths = {length1, length2};
- int[] bounds = null;
- return CreateInstanceImpl (elementType, lengths, bounds);
+ return CreateInstance (elementType, lengths);
}
public static Array CreateInstance (Type elementType, int length1, int length2, int length3)
{
int[] lengths = {length1, length2, length3};
- int[] bounds = null;
- return CreateInstanceImpl (elementType, lengths, bounds);
+ return CreateInstance (elementType, lengths);
}
- public static Array CreateInstance (Type elementType, int[] lengths)
+ public static Array CreateInstance (Type elementType, params int[] lengths)
{
if (elementType == null)
throw new ArgumentNullException ("elementType");
throw new TypeLoadException ();
int[] bounds = null;
+
+ elementType = elementType.UnderlyingSystemType;
+ if (!elementType.IsSystemType)
+ throw new ArgumentException ("Type must be a type provided by the runtime.", "elementType");
return CreateInstanceImpl (elementType, lengths, bounds);
}
if (bounds == null)
throw new ArgumentNullException ("bounds");
+ elementType = elementType.UnderlyingSystemType;
+ if (!elementType.IsSystemType)
+ throw new ArgumentException ("Type must be a type provided by the runtime.", "elementType");
+
if (lengths.Length < 1)
throw new ArgumentException (Locale.GetText ("Arrays must contain >= 1 elements."));
public static Array CreateInstance (Type elementType, params long [] lengths)
{
- if (lengths == null) {
- // LAMESPEC: Docs say we should throw a ArgumentNull, but .NET
- // 1.1 actually throws a NullReference.
- throw new NullReferenceException (Locale.GetText ("'lengths' cannot be null."));
- }
+#if NET_2_0
+ if (lengths == null)
+ throw new ArgumentNullException ("lengths");
+#endif
return CreateInstance (elementType, GetIntArray (lengths));
}
[ComVisible (false)]
- public object GetValue (long [] indices)
+ public object GetValue (params long [] indices)
{
- if (indices == null) {
- // LAMESPEC: Docs say we should throw a ArgumentNull, but .NET
- // 1.1 actually throws a NullReference.
- throw new NullReferenceException (Locale.GetText ("'indices' cannot be null."));
- }
+#if NET_2_0
+ if (indices == null)
+ throw new ArgumentNullException ("indices");
+#endif
return GetValue (GetIntArray (indices));
}
[ComVisible (false)]
- public void SetValue (object value, long [] indices)
+ public void SetValue (object value, params long [] indices)
{
- if (indices == null) {
- // LAMESPEC: Docs say we should throw a ArgumentNull, but .NET
- // 1.1 actually throws a NullReference.
- throw new NullReferenceException (Locale.GetText ("'indices' cannot be null."));
- }
+#if NET_2_0
+ if (indices == null)
+ throw new ArgumentNullException ("indices");
+#endif
SetValue (value, GetIntArray (indices));
}
#endif
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
-#endif
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+#endif
public static int BinarySearch (Array array, object value)
{
if (array == null)
if (array.Rank > 1)
throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
+ if (array.Length == 0)
+ return -1;
+
if (!(value is IComparable))
throw new ArgumentException (Locale.GetText ("value does not support IComparable."));
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int BinarySearch (Array array, object value, IComparer comparer)
{
if (array.Rank > 1)
throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
+ if (array.Length == 0)
+ return -1;
+
if ((comparer == null) && (value != null) && !(value is IComparable))
throw new ArgumentException (Locale.GetText (
"comparer is null and value does not support IComparable."));
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int BinarySearch (Array array, int index, int length, object value)
{
if (index > array.GetLowerBound (0) + array.GetLength (0) - length)
throw new ArgumentException (Locale.GetText (
"index and length do not specify a valid range in array."));
+
+ if (array.Length == 0)
+ return -1;
+
if ((value != null) && (!(value is IComparable)))
throw new ArgumentException (Locale.GetText (
"value does not support IComparable"));
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int BinarySearch (Array array, int index, int length, object value, IComparer comparer)
{
throw new ArgumentException (Locale.GetText (
"index and length do not specify a valid range in array."));
+ if (array.Length == 0)
+ return -1;
+
if ((comparer == null) && (value != null) && !(value is IComparable))
throw new ArgumentException (Locale.GetText (
"comparer is null and value does not support IComparable."));
int iCmp = 0;
try {
while (iMin <= iMax) {
- int iMid = (iMin + iMax) / 2;
+ // Be careful with overflow
+ // http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html
+ int iMid = iMin + ((iMax - iMin) / 2);
object elt = array.GetValueImpl (iMid);
- iCmp = comparer.Compare (value, elt);
+ iCmp = comparer.Compare (elt, value);
if (iCmp == 0)
return iMid;
- else if (iCmp < 0)
+ else if (iCmp > 0)
iMax = iMid - 1;
else
iMin = iMid + 1; // compensate for the rounding down
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.Success)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
#endif
public static void Clear (Array array, int index, int length)
{
static extern void ClearInternal (Array a, int index, int count);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- public virtual extern object Clone ();
+ public
+#if !NET_2_0
+ virtual
+#endif
+ extern object Clone ();
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Copy (Array sourceArray, Array destinationArray, int length)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Copy (Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length)
{
int dest_pos = destinationIndex - destinationArray.GetLowerBound (0);
// re-ordered to avoid possible integer overflow
- if (source_pos > sourceArray.Length - length || dest_pos > destinationArray.Length - length)
+ if (source_pos > sourceArray.Length - length)
throw new ArgumentException ("length");
+ if (dest_pos > destinationArray.Length - length) {
+ string msg = "Destination array was not long enough. Check " +
+ "destIndex and length, and the array's lower bounds";
+#if NET_2_0
+ throw new ArgumentException (msg, string.Empty);
+#else
+ throw new ArgumentException (msg);
+#endif
+ }
+
if (sourceArray.Rank != destinationArray.Rank)
throw new RankException (Locale.GetText ("Arrays must be of same size."));
#if NET_1_1
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Copy (Array sourceArray, long sourceIndex, Array destinationArray,
long destinationIndex, long length)
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Copy (Array sourceArray, Array destinationArray, long length)
{
#endif
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int IndexOf (Array array, object value)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int IndexOf (Array array, object value, int startIndex)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int IndexOf (Array array, object value, int startIndex, int count)
{
return array.GetLowerBound (0) - 1;
}
- [MonoTODO]
public void Initialize()
{
//FIXME: We would like to find a compiler that uses
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int LastIndexOf (Array array, object value)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int LastIndexOf (Array array, object value, int startIndex)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
public static int LastIndexOf (Array array, object value, int startIndex, int count)
{
return array.GetLowerBound (0) - 1;
}
-#if !BOOTSTRAP_WITH_OLDLIB && !NET_2_0
+#if !BOOTSTRAP_WITH_OLDLIB
/* delegate used to swap array elements */
delegate void Swapper (int i, int j);
#endif
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ static Swapper get_swapper<T> (T [] array)
+ {
+ if (array is int[])
+ return new Swapper (array.int_swapper);
+ if (array is double[])
+ return new Swapper (array.double_swapper);
+
+ // gmcs refuses to compile this
+ //return new Swapper (array.generic_swapper<T>);
+ return new Swapper (array.slow_swapper);
+ }
+#endif
+
+#if NET_2_0
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Reverse (Array array)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Reverse (Array array, int index, int length)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Sort (Array array)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Sort (Array keys, Array items)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Sort (Array array, IComparer comparer)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Sort (Array array, int index, int length)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Sort (Array keys, Array items, IComparer comparer)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Sort (Array keys, Array items, int index, int length)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
public static void Sort (Array array, int index, int length, IComparer comparer)
{
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.MayCorruptInstance, CER.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
#endif
+
public static void Sort (Array keys, Array items, int index, int length, IComparer comparer)
{
if (keys == null)
throw new ArgumentOutOfRangeException ("length", Locale.GetText (
"Value has to be >= 0."));
- if (keys.Length - (index + keys.GetLowerBound (0)) < length
- || (items != null && index > items.Length - length))
+ if (keys.Length - (index + keys.GetLowerBound (0)) < length || (items != null && index > items.Length - length))
throw new ArgumentException ();
if (length <= 1)
array [j] = val;
}
+#if NET_2_0
+ void generic_swapper<T> (int i, int j) {
+ T[] array = this as T[];
+ T val = array [i];
+ array [i] = array [j];
+ array [j] = val;
+ }
+#endif
+
static int new_gap (int gap)
{
gap = (gap * 10) / 13;
int low = low0;
int high = high0;
- object objPivot = keys.GetValueImpl ((low + high) / 2);
+ // Be careful with overflows
+ int mid = low + ((high - low) / 2);
+ object objPivot = keys.GetValueImpl (mid);
while (low <= high) {
// Move the walls in
return comparer.Compare (value1, value2);
}
- public virtual void CopyTo (Array array, int index)
+#if NET_2_0
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Sort<T> (T [] array)
+ {
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ Sort<T, T> (array, null, 0, array.Length, null);
+ }
+
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items)
+ {
+ if (keys == null)
+ throw new ArgumentNullException ("keys");
+
+ Sort<TKey, TValue> (keys, items, 0, keys.Length, null);
+ }
+
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Sort<T> (T [] array, IComparer<T> comparer)
+ {
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ Sort<T, T> (array, null, 0, array.Length, comparer);
+ }
+
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items, IComparer<TKey> comparer)
+ {
+ if (keys == null)
+ throw new ArgumentNullException ("keys");
+
+ Sort<TKey, TValue> (keys, items, 0, keys.Length, comparer);
+ }
+
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Sort<T> (T [] array, int index, int length)
+ {
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ Sort<T, T> (array, null, index, length, null);
+ }
+
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items, int index, int length)
+ {
+ Sort<TKey, TValue> (keys, items, index, length, null);
+ }
+
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Sort<T> (T [] array, int index, int length, IComparer<T> comparer)
+ {
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ Sort<T, T> (array, null, index, length, comparer);
+ }
+
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items, int index, int length, IComparer<TKey> comparer)
+ {
+ if (keys == null)
+ throw new ArgumentNullException ("keys");
+
+ if (index < 0)
+ throw new ArgumentOutOfRangeException ("index");
+
+ if (length < 0)
+ throw new ArgumentOutOfRangeException ("length");
+
+ if (keys.Length - index < length
+ || (items != null && index > items.Length - length))
+ throw new ArgumentException ();
+
+ if (length <= 1)
+ return;
+
+ //
+ // Check for value types which can be sorted without Compare () method
+ //
+ if (comparer == null) {
+ Swapper iswapper;
+ if (items == null)
+ iswapper = null;
+ else
+ iswapper = get_swapper<TValue> (items);
+ if (keys is double[]) {
+ combsort (keys as double[], index, length, iswapper);
+ return;
+ }
+ if (keys is int[]) {
+ combsort (keys as int[], index, length, iswapper);
+ return;
+ }
+ if (keys is char[]) {
+ combsort (keys as char[], index, length, iswapper);
+ return;
+ }
+
+ // Use Comparer<T>.Default instead
+ // comparer = Comparer<K>.Default;
+ }
+
+ try {
+ int low0 = index;
+ int high0 = index + length - 1;
+ qsort<TKey, TValue> (keys, items, low0, high0, comparer);
+ }
+ catch (Exception e) {
+ throw new InvalidOperationException (Locale.GetText ("The comparer threw an exception."), e);
+ }
+ }
+
+ public static void Sort<T> (T [] array, Comparison<T> comparison)
+ {
+ if (array == null)
+ throw new ArgumentNullException ("array");
+ Sort<T> (array, array.Length, comparison);
+ }
+
+ internal static void Sort<T> (T [] array, int length, Comparison<T> comparison)
+ {
+ if (comparison == null)
+ throw new ArgumentNullException ("comparison");
+
+ if (length <= 1 || array.Length <= 1)
+ return;
+
+ try {
+ int low0 = 0;
+ int high0 = length - 1;
+ qsort<T> (array, low0, high0, comparison);
+ }
+ catch (Exception e) {
+ throw new InvalidOperationException (Locale.GetText ("Comparison threw an exception."), e);
+ }
+ }
+
+ private static void qsort<K, V> (K [] keys, V [] items, int low0, int high0, IComparer<K> comparer)
+ {
+ if (low0 >= high0)
+ return;
+
+ int low = low0;
+ int high = high0;
+
+ // Be careful with overflows
+ int mid = low + ((high - low) / 2);
+ K keyPivot = keys [mid];
+
+ while (low <= high) {
+ // Move the walls in
+ //while (low < high0 && comparer.Compare (keys [low], keyPivot) < 0)
+ while (low < high0 && compare (keys [low], keyPivot, comparer) < 0)
+ ++low;
+ //while (high > low0 && comparer.Compare (keyPivot, keys [high]) < 0)
+ while (high > low0 && compare (keyPivot, keys [high], comparer) < 0)
+ --high;
+
+ if (low <= high) {
+ swap<K, V> (keys, items, low, high);
+ ++low;
+ --high;
+ }
+ }
+
+ if (low0 < high)
+ qsort<K, V> (keys, items, low0, high, comparer);
+ if (low < high0)
+ qsort<K, V> (keys, items, low, high0, comparer);
+ }
+
+ private static int compare<T> (T value1, T value2, IComparer<T> comparer)
+ {
+ if (comparer != null)
+ return comparer.Compare (value1, value2);
+ else if (value1 == null)
+ return value2 == null ? 0 : -1;
+ else if (value2 == null)
+ return 1;
+ else if (value1 is IComparable<T>)
+ return ((IComparable<T>) value1).CompareTo (value2);
+ else if (value1 is IComparable)
+ return ((IComparable) value1).CompareTo (value2);
+
+ string msg = Locale.GetText ("No IComparable or IComparable<T> interface found for type '{0}'.");
+ throw new InvalidOperationException (String.Format (msg, typeof (T)));
+ }
+
+ private static void qsort<T> (T [] array, int low0, int high0, Comparison<T> comparison)
+ {
+ if (low0 >= high0)
+ return;
+
+ int low = low0;
+ int high = high0;
+
+ // Be careful with overflows
+ int mid = low + ((high - low) / 2);
+ T keyPivot = array [mid];
+
+ while (low <= high) {
+ // Move the walls in
+ while (low < high0 && comparison (array [low], keyPivot) < 0)
+ ++low;
+ while (high > low0 && comparison (keyPivot, array [high]) < 0)
+ --high;
+
+ if (low <= high) {
+ swap<T> (array, low, high);
+ ++low;
+ --high;
+ }
+ }
+
+ if (low0 < high)
+ qsort<T> (array, low0, high, comparison);
+ if (low < high0)
+ qsort<T> (array, low, high0, comparison);
+ }
+
+ private static void swap<K, V> (K [] keys, V [] items, int i, int j)
+ {
+ K tmp;
+
+ tmp = keys [i];
+ keys [i] = keys [j];
+ keys [j] = tmp;
+
+ if (items != null) {
+ V itmp;
+ itmp = items [i];
+ items [i] = items [j];
+ items [j] = itmp;
+ }
+ }
+
+ private static void swap<T> (T [] array, int i, int j)
+ {
+ T tmp = array [i];
+ array [i] = array [j];
+ array [j] = tmp;
+ }
+#endif
+
+ public
+#if !NET_2_0
+ virtual
+#endif
+ void CopyTo (Array array, int index)
{
if (array == null)
throw new ArgumentNullException ("array");
if (this.Rank > 1)
throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
if (index + this.GetLength (0) > array.GetLowerBound (0) + array.GetLength (0))
- throw new ArgumentException ();
+ throw new ArgumentException ("Destination array was not long " +
+ "enough. Check destIndex and length, and the array's " +
+ "lower bounds.");
if (array.Rank > 1)
throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
if (index < 0)
#if NET_1_1
[ComVisible (false)]
- public virtual void CopyTo (Array array, long index)
+ public
+#if !NET_2_0
+ virtual
+#endif
+ void CopyTo (Array array, long index)
{
if (index < 0 || index > Int32.MaxValue)
throw new ArgumentOutOfRangeException ("index", Locale.GetText (
return MemberwiseClone ();
}
}
+
#if NET_2_0
- [CLSCompliant (false)]
- public static void Resize <T> (ref T [] arr, int sz) {
- if (sz < 0)
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static void Resize<T> (ref T [] array, int newSize)
+ {
+ Resize<T> (ref array, array == null ? 0 : array.Length, newSize);
+ }
+
+ internal static void Resize<T> (ref T[] array, int length, int newSize)
+ {
+ if (newSize < 0)
throw new ArgumentOutOfRangeException ();
- if (arr == null) {
- arr = new T [sz];
+ if (array == null) {
+ array = new T [newSize];
return;
}
- if (arr.Length == sz)
+ if (array.Length == newSize)
return;
- T [] a = new T [sz];
- Array.Copy (arr, a, Math.Min (sz, arr.Length));
- arr = a;
+ T [] a = new T [newSize];
+ Array.Copy (array, a, Math.Min (newSize, length));
+ array = a;
}
- [CLSCompliant (false)]
- public static bool TrueForAll <T> (T [] array, Predicate <T> p)
+ public static bool TrueForAll <T> (T [] array, Predicate <T> match)
{
- if (array == null || p == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
+ if (match == null)
+ throw new ArgumentNullException ("match");
foreach (T t in array)
- if (! p (t))
+ if (! match (t))
return false;
return true;
}
- [CLSCompliant (false)]
- public static void ForEach <T> (T [] array, Action <T> a)
+
+ public static void ForEach<T> (T [] array, Action <T> action)
{
- if (array == null || a == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
+ if (action == null)
+ throw new ArgumentNullException ("action");
foreach (T t in array)
- a (t);
+ action (t);
}
- [CLSCompliant (false)]
- public static U [] ConvertAll <T, U> (T [] s, Converter <T, U> c)
+ public static TOutput[] ConvertAll<TInput, TOutput> (TInput [] array, Converter<TInput, TOutput> converter)
{
- if (s == null || c == null)
- throw new ArgumentNullException ();
-
- U [] r = new U [s.Length];
+ if (array == null)
+ throw new ArgumentNullException ("array");
+ if (converter == null)
+ throw new ArgumentNullException ("converter");
- for (int i = 0; i < s.Length; i ++)
- r [i] = c (s [i]);
+ TOutput [] output = new TOutput [array.Length];
+ for (int i = 0; i < array.Length; i ++)
+ output [i] = converter (array [i]);
- return r;
+ return output;
}
- [CLSCompliant (false)]
- public static int FindLastIndex <T> (T [] a, Predicate <T> c)
+ public static int FindLastIndex<T> (T [] array, Predicate <T> match)
{
- if (a == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
- return FindLastIndex <T> (a, 0, a.Length, c);
+ return FindLastIndex<T> (array, 0, array.Length, match);
}
- [CLSCompliant (false)]
- public static int FindLastIndex <T> (T [] a, int idx, Predicate <T> c)
+ public static int FindLastIndex<T> (T [] array, int startIndex, Predicate<T> match)
{
- if (a == null)
+ if (array == null)
throw new ArgumentNullException ();
- return FindLastIndex <T> (a, idx, a.Length - idx, c);
+ return FindLastIndex<T> (array, startIndex, array.Length - startIndex, match);
}
- [CLSCompliant (false)]
- public static int FindLastIndex <T> (T [] a, int idx, int cnt, Predicate <T> c)
+ public static int FindLastIndex<T> (T [] array, int startIndex, int count, Predicate<T> match)
{
- if (a == null || c == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
+ if (match == null)
+ throw new ArgumentNullException ("match");
- if (idx > a.Length || idx + cnt > a.Length)
+ if (startIndex > array.Length || startIndex + count > array.Length)
throw new ArgumentOutOfRangeException ();
- for (int i = idx + cnt - 1; i >= idx; i --)
- if (c (a [i]))
+ for (int i = startIndex + count - 1; i >= startIndex; i--)
+ if (match (array [i]))
return i;
return -1;
}
- [CLSCompliant (false)]
- public static int FindIndex <T> (T [] a, Predicate <T> c)
+ public static int FindIndex<T> (T [] array, Predicate<T> match)
{
- if (a == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
- return FindIndex <T> (a, 0, a.Length, c);
+ return FindIndex<T> (array, 0, array.Length, match);
}
- [CLSCompliant (false)]
- public static int FindIndex <T> (T [] a, int idx, Predicate <T> c)
+ public static int FindIndex<T> (T [] array, int startIndex, Predicate<T> match)
{
- if (a == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
- return FindIndex <T> (a, idx, a.Length - idx, c);
+ return FindIndex<T> (array, startIndex, array.Length - startIndex, match);
}
- [CLSCompliant (false)]
- public static int FindIndex <T> (T [] a, int idx, int cnt, Predicate <T> c)
+ public static int FindIndex<T> (T [] array, int startIndex, int count, Predicate<T> match)
{
- if (a == null || c == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
- if (idx > a.Length || idx + cnt > a.Length)
+ if (match == null)
+ throw new ArgumentNullException ("match");
+
+ if (startIndex > array.Length || startIndex + count > array.Length)
throw new ArgumentOutOfRangeException ();
- for (int i = idx; i < idx + cnt; i ++)
- if (c (a [i]))
+ for (int i = startIndex; i < startIndex + count; i ++)
+ if (match (array [i]))
return i;
return -1;
}
- [CLSCompliant (false)]
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
- public static int BinarySearch <T> (T [] array, T value)
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static int BinarySearch<T> (T [] array, T value)
{
if (array == null)
throw new ArgumentNullException ("array");
- return BinarySearch <T> (array, 0, array.Length, value, null);
+ return BinarySearch<T> (array, 0, array.Length, value, null);
}
- [CLSCompliant (false)]
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
- public static int BinarySearch <T> (T [] array, T value, IComparer <T> comparer)
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static int BinarySearch<T> (T [] array, T value, IComparer<T> comparer)
{
if (array == null)
throw new ArgumentNullException ("array");
- return BinarySearch <T> (array, 0, array.Length, value, comparer);
+ return BinarySearch<T> (array, 0, array.Length, value, comparer);
}
- [CLSCompliant (false)]
- public static int BinarySearch <T> (T [] array, int offset, int length, T value)
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static int BinarySearch<T> (T [] array, int offset, int length, T value)
{
- return BinarySearch <T> (array, offset, length, value, null);
+ return BinarySearch<T> (array, offset, length, value, null);
}
- [CLSCompliant (false)]
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.MayFail)]
- public static int BinarySearch <T> (T [] array, int index, int length, T value, IComparer <T> comparer)
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static int BinarySearch<T> (T [] array, int index, int length, T value, IComparer<T> comparer)
{
if (array == null)
throw new ArgumentNullException ("array");
int iCmp = 0;
try {
while (iMin <= iMax) {
- int iMid = (iMin + iMax) / 2;
+ // Be careful with overflows
+ int iMid = iMin + ((iMax - iMin) / 2);
iCmp = comparer.Compare (value, array [iMid]);
if (iCmp == 0)
else
iMin = iMid + 1; // compensate for the rounding down
}
- }
- catch (Exception e) {
+ } catch (Exception e) {
throw new InvalidOperationException (Locale.GetText ("Comparer threw an exception."), e);
}
return ~iMin;
}
- [CLSCompliant (false)]
- public static int IndexOf <T> (T [] array, T value)
+ public static int IndexOf<T> (T [] array, T value)
{
if (array == null)
throw new ArgumentNullException ("array");
- return IndexOf (array, value, 0, array.Length);
+ return IndexOf<T> (array, value, 0, array.Length);
}
- [CLSCompliant (false)]
- public static int IndexOf <T> (T [] array, T value, int startIndex)
+ public static int IndexOf<T> (T [] array, T value, int startIndex)
{
if (array == null)
throw new ArgumentNullException ("array");
- return IndexOf (array, value, startIndex, array.Length - startIndex);
+ return IndexOf<T> (array, value, startIndex, array.Length - startIndex);
}
- [CLSCompliant (false)]
- public static int IndexOf <T> (T [] array, T value, int startIndex, int count)
+ public static int IndexOf<T> (T [] array, T value, int startIndex, int count)
{
if (array == null)
throw new ArgumentNullException ("array");
throw new ArgumentOutOfRangeException ();
int max = startIndex + count;
+ EqualityComparer<T> equalityComparer = EqualityComparer<T>.Default;
for (int i = startIndex; i < max; i++) {
- if (Object.Equals (value, array [i]))
+ if (equalityComparer.Equals (value, array [i]))
return i;
}
return -1;
}
- [CLSCompliant (false)]
- public static int LastIndexOf <T> (T [] array, T value)
+ public static int LastIndexOf<T> (T [] array, T value)
{
if (array == null)
throw new ArgumentNullException ("array");
- return LastIndexOf (array, value, array.Length - 1);
+ return LastIndexOf<T> (array, value, array.Length - 1);
}
- [CLSCompliant (false)]
- public static int LastIndexOf <T> (T [] array, T value, int startIndex)
+ public static int LastIndexOf<T> (T [] array, T value, int startIndex)
{
if (array == null)
throw new ArgumentNullException ("array");
- return LastIndexOf (array, value, startIndex, startIndex + 1);
+ return LastIndexOf<T> (array, value, startIndex, startIndex + 1);
}
- [CLSCompliant (false)]
- public static int LastIndexOf <T> (T [] array, T value, int startIndex, int count)
+ public static int LastIndexOf<T> (T [] array, T value, int startIndex, int count)
{
if (array == null)
throw new ArgumentNullException ("array");
if (count < 0 || startIndex > array.Length || startIndex - count + 1 < 0)
throw new ArgumentOutOfRangeException ();
+ EqualityComparer<T> equalityComparer = EqualityComparer<T>.Default;
for (int i = startIndex; i >= startIndex - count + 1; i--) {
- if (Object.Equals (value, array [i]))
+ if (equalityComparer.Equals (value, array [i]))
return i;
}
return -1;
}
- [CLSCompliant (false)]
- public static T [] FindAll <T> (T [] a, Predicate <T> p)
+ public static T [] FindAll<T> (T [] array, Predicate <T> match)
{
- if (a == null || p == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ if (match == null)
+ throw new ArgumentNullException ("match");
int pos = 0;
- T [] d = new T [a.Length];
- foreach (T t in a)
- if (p (t))
- d [pos ++] = t;
+ T [] d = new T [array.Length];
+ foreach (T t in array)
+ if (match (t))
+ d [pos++] = t;
- Resize <T> (ref a, pos);
- return a;
+ Resize <T> (ref d, pos);
+ return d;
}
- [CLSCompliant (false)]
- public static bool Exists <T> (T [] a, Predicate <T> p)
+ public static bool Exists<T> (T [] array, Predicate <T> match)
{
- if (a == null || p == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ if (match == null)
+ throw new ArgumentNullException ("match");
- foreach (T t in a)
- if (p (t))
+ foreach (T t in array)
+ if (match (t))
return true;
return false;
}
- [CLSCompliant (false)]
- public static IList<T> AsReadOnly<T> (T[] array)
+ public static ReadOnlyCollection<T> AsReadOnly<T> (T[] array)
{
if (array == null)
throw new ArgumentNullException ("array");
- return new ReadOnlyArray <T> (array);
+ return new ReadOnlyCollection<T> (new ArrayReadOnlyList<T> (array));
}
-
-#if FIXME
- [CLSCompliant (false)]
- public static Nullable <T> Find <T> (T [] a, Predicate <T> p)
+
+ public static T Find<T> (T [] array, Predicate<T> match)
{
- if (a == null || p == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ if (match == null)
+ throw new ArgumentNullException ("match");
- foreach (T t in a)
- if (p (t))
- return new Nullable <T> (t);
+ foreach (T t in array)
+ if (match (t))
+ return t;
- return default (Nullable <T>);
+ return default (T);
}
- [CLSCompliant (false)]
- public static Nullable <T> FindLast <T> (T [] a, Predicate <T> p)
+ public static T FindLast<T> (T [] array, Predicate <T> match)
{
- if (a == null || p == null)
- throw new ArgumentNullException ();
+ if (array == null)
+ throw new ArgumentNullException ("array");
+
+ if (match == null)
+ throw new ArgumentNullException ("match");
- for (int i = a.Length - 1; i >= 0; i--)
- if (p (a [i]))
- return new Nullable <T> (a [i]);
+ for (int i = array.Length - 1; i >= 0; i--)
+ if (match (array [i]))
+ return array [i];
- return default (Nullable <T>);
+ return default (T);
}
-#endif
-#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, CER.Success)]
-#endif
- // Fixme: wtf is constrained about this
+ [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
+ //
+ // The constrained copy should guarantee that if there is an exception thrown
+ // during the copy, the destination array remains unchanged.
+ // This is related to System.Runtime.Reliability.CER
public static void ConstrainedCopy (Array s, int s_i, Array d, int d_i, int c)
{
Copy (s, s_i, d, d_i, c);
- }
-#endif
- }
-
+ }
+#endif
#if NET_2_0
-
- internal struct ReadOnlyArrayEnumerator <T> : IEnumerator <T> {
- const int NOT_STARTED = -2;
-
- // this MUST be -1, because we depend on it in move next.
- // we just decr the size, so, 0 - 1 == FINISHED
- const int FINISHED = -1;
-
- ReadOnlyArray <T> array;
- int idx;
-
- internal ReadOnlyArrayEnumerator (ReadOnlyArray<T> array)
+ class ArrayReadOnlyList<T> : IList<T>
{
- this.array = array;
- idx = NOT_STARTED;
- }
-
- public void Dispose ()
- {
- idx = NOT_STARTED;
- }
-
- public bool MoveNext ()
- {
- if (idx == NOT_STARTED)
- idx = array.Count;
-
- return idx != FINISHED && -- idx != FINISHED;
- }
-
- public T Current {
- get {
- if (idx < 0)
- throw new InvalidOperationException ();
-
- return array [array.Count - 1 - idx];
+ T [] array;
+ bool is_value_type;
+
+ public ArrayReadOnlyList (T [] array)
+ {
+ this.array = array;
+ is_value_type = typeof (T).IsValueType;
}
- }
- }
- internal class ReadOnlyArray <T> : ICollection <T>, IList <T>, IEnumerable <T>
- {
- T[] arr;
+ public T this [int index] {
+ get {
+ if (unchecked ((uint) index) >= unchecked ((uint) array.Length))
+ throw new ArgumentOutOfRangeException ("index");
+ return array [index];
+ }
+ set { throw ReadOnlyError (); }
+ }
- internal ReadOnlyArray (T[] array) {
- arr = array;
- }
+ public int Count {
+ get { return array.Length; }
+ }
- // ICollection<T> interface
- public int Count {
- get {
- return arr.Length;
+ public bool IsReadOnly {
+ get { return true; }
}
- }
- public bool IsReadOnly {
- get {
- return true;
+ public void Add (T item)
+ {
+ throw ReadOnlyError ();
}
- }
- public void Add (T item) {
- throw new NotSupportedException ("Collection is read-only");
- }
+ public void Clear ()
+ {
+ throw ReadOnlyError ();
+ }
- public bool Remove (T item) {
- throw new NotSupportedException ("Collection is read-only");
- }
+ public bool Contains (T item)
+ {
+ return Array.IndexOf<T> (array, item) >= 0;
+ }
- public void Clear () {
- throw new NotSupportedException ("Collection is read-only");
- }
+ public void CopyTo (T [] array, int index)
+ {
+ array.CopyTo (array, index);
+ }
- public void CopyTo (T[] array, int index) {
- arr.CopyTo (array, index);
- }
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return GetEnumerator ();
+ }
- public bool Contains (T item) {
- return Array.IndexOf <T> (arr, item) != -1;
- }
+ public IEnumerator<T> GetEnumerator ()
+ {
+ for (int i = 0; i < array.Length; i++)
+ yield return array [i];
+ }
- // IList<T> interface
- public T this [int index] {
- get {
- if (unchecked ((uint) index) >= unchecked ((uint) arr.Length))
- throw new ArgumentOutOfRangeException ("index");
- return arr [index];
- }
- set {
- if (unchecked ((uint) index) >= unchecked ((uint) arr.Length))
- throw new ArgumentOutOfRangeException ("index");
- arr [index] = value;
+ public int IndexOf (T item)
+ {
+ return Array.IndexOf<T> (array, item);
}
- }
- public void Insert (int index, T item) {
- throw new NotSupportedException ("Collection is read-only");
- }
+ public void Insert (int index, T item)
+ {
+ throw ReadOnlyError ();
+ }
- public void RemoveAt (int index) {
- throw new NotSupportedException ("Collection is read-only");
- }
+ public bool Remove (T item)
+ {
+ throw ReadOnlyError ();
+ }
- public int IndexOf (T item) {
- return Array.IndexOf <T> (arr, item);
- }
+ public void RemoveAt (int index)
+ {
+ throw ReadOnlyError ();
+ }
- // IEnumerable<T> interface
- public IEnumerator<T> GetEnumerator () {
- return new ReadOnlyArrayEnumerator <T> (this);
+ Exception ReadOnlyError ()
+ {
+ return new NotSupportedException ("This collection is read-only.");
+ }
}
- }
-
#endif
+ }
-#if BOOTSTRAP_WITH_OLDLIB || NET_2_0
+#if BOOTSTRAP_WITH_OLDLIB
/* delegate used to swap array elements, keep defined outside Array */
delegate void Swapper (int i, int j);
#endif