namespace System
{
[Serializable]
+#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
}
#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;
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;
}
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)
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
protected void InternalArray__set_Item<T> (int index, T item)
{
- throw new NotSupportedException ("Collection is read-only");
+ 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;
public T Current {
get {
- if (idx < 0)
- throw new InvalidOperationException ();
+ if (idx == NOT_STARTED)
+ throw new InvalidOperationException ("Enumeration has not started. Call MoveNext");
+ if (idx == FINISHED)
+ throw new InvalidOperationException ("Enumeration already finished");
return array.InternalArray__get_Item<T> (array.Length - 1 - idx);
}
void IEnumerator.Reset ()
{
- throw new NotImplementedException ();
+ idx = NOT_STARTED;
}
object IEnumerator.Current {
// InternalCall Methods
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- protected extern int GetRank ();
+ extern int GetRank ();
[MethodImplAttribute (MethodImplOptions.InternalCall)]
public extern int GetLength (int dimension);
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");
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 (elt, value);
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 (array is double[])
return new Swapper (array.double_swapper);
- return new Swapper (array.obj_swapper);
+ // gmcs refuses to compile this
+ //return new Swapper (array.generic_swapper<T>);
+ return new Swapper (array.slow_swapper);
}
#endif
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
}
#if NET_2_0
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T> (T [] array)
{
if (array == null)
Sort<T, T> (array, null, 0, array.Length, null);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items)
{
if (keys == null)
Sort<TKey, TValue> (keys, items, 0, keys.Length, null);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T> (T [] array, IComparer<T> comparer)
{
if (array == null)
Sort<T, T> (array, null, 0, array.Length, comparer);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<TKey, TValue> (TKey [] keys, TValue [] items, IComparer<TKey> comparer)
{
if (keys == null)
Sort<TKey, TValue> (keys, items, 0, keys.Length, comparer);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T> (T [] array, int index, int length)
{
if (array == null)
Sort<T, T> (array, null, index, length, null);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [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.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T> (T [] array, int index, int length, IComparer<T> comparer)
{
if (array == null)
Sort<T, T> (array, null, index, length, comparer);
}
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
+ [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)
int low = low0;
int high = high0;
- K keyPivot = keys [(low + high) / 2];
+ // Be careful with overflows
+ int mid = low + ((high - low) / 2);
+ K keyPivot = keys [mid];
while (low <= high) {
// Move the walls in
int low = low0;
int high = high0;
- T keyPivot = array [(low + high) / 2];
+ // Be careful with overflows
+ int mid = low + ((high - low) / 2);
+ T keyPivot = array [mid];
while (low <= high) {
// Move the walls in
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)
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)