[runtime] Fix Empty generic enumerator equality
[mono.git] / mcs / class / corlib / System / Array.cs
index 946647ae149da3a979b204fbb60b6fb4a704e051..91424bc6f8f6dfbf4d2c5457e453f4db01add388 100644 (file)
@@ -68,7 +68,10 @@ namespace System
 
                internal IEnumerator<T> InternalArray__IEnumerable_GetEnumerator<T> ()
                {
-                       return new InternalEnumerator<T> (this);
+                       if (Length == 0)
+                               return EmptyInternalEnumerator<T>.Value;
+                       else
+                               return new InternalEnumerator<T> (this);
                }
 
                internal void InternalArray__ICollection_Clear ()
@@ -207,7 +210,7 @@ namespace System
                        // we just decr the size, so, 0 - 1 == FINISHED
                        const int FINISHED = -1;
                        
-                       Array array;
+                       readonly Array array;
                        int idx;
 
                        internal InternalEnumerator (Array array)
@@ -218,7 +221,6 @@ namespace System
 
                        public void Dispose ()
                        {
-                               idx = NOT_STARTED;
                        }
 
                        public bool MoveNext ()
@@ -272,6 +274,38 @@ namespace System
                        }
                }
 
+               internal class EmptyInternalEnumerator<T> : IEnumerator<T>
+               {
+                       public static readonly EmptyInternalEnumerator<T> Value = new EmptyInternalEnumerator<T> ();
+
+                       public void Dispose ()
+                       {
+                               return;
+                       }
+
+                       public bool MoveNext ()
+                       {
+                               return false;
+                       }
+
+                       public T Current {
+                               get {
+                                       throw new InvalidOperationException ("Enumeration has not started. Call MoveNext");
+                               }
+                       }
+
+                       object IEnumerator.Current {
+                               get {
+                                       return Current;
+                               }
+                       }
+
+                       void IEnumerator.Reset ()
+                       {
+                               return;
+                       }
+               }
+
                // InternalCall Methods
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern int GetRank ();
@@ -312,12 +346,17 @@ namespace System
                public object GetValue (int index)
                {
                        if (Rank != 1)
-                               throw new ArgumentException (Locale.GetText ("Array was not a one-dimensional array."));
-                       if (index < GetLowerBound (0) || index > GetUpperBound (0))
+                               throw new ArgumentException (SR.Arg_RankMultiDimNotSupported);
+
+                       var lb  = GetLowerBound (0);
+                       if (index < lb || index > GetUpperBound (0))
                                throw new IndexOutOfRangeException (Locale.GetText (
                                        "Index has to be between upper and lower bound of the array."));
 
-                       return GetValueImpl (index - GetLowerBound (0));
+                       if (GetType ().GetElementType ().IsPointer)
+                               throw new NotSupportedException ("Type is not supported");
+
+                       return GetValueImpl (index - lb);
                }
 
                public object GetValue (int index1, int index2)
@@ -335,12 +374,17 @@ namespace System
                public void SetValue (object value, int index)
                {
                        if (Rank != 1)
-                               throw new ArgumentException (Locale.GetText ("Array was not a one-dimensional array."));
-                       if (index < GetLowerBound (0) || index > GetUpperBound (0))
+                               throw new ArgumentException (SR.Arg_RankMultiDimNotSupported);
+
+                       var lb  = GetLowerBound (0);
+                       if (index < lb || index > GetUpperBound (0))
                                throw new IndexOutOfRangeException (Locale.GetText (
                                        "Index has to be >= lower bound and <= upper bound of the array."));
 
-                       SetValueImpl (value, index - GetLowerBound (0));
+                       if (GetType ().GetElementType ().IsPointer)
+                               throw new NotSupportedException ("Type is not supported");
+
+                       SetValueImpl (value, index - lb);
                }
 
                public void SetValue (object value, int index1, int index2)
@@ -589,31 +633,6 @@ namespace System
                        return source.IsAssignableFrom (target) || target.IsAssignableFrom (source);
                }
 
-               public static T[] FindAll<T> (T[] array, Predicate<T> match)
-               {
-                       if (array == null)
-                               throw new ArgumentNullException ("array");
-
-                       if (match == null)
-                               throw new ArgumentNullException ("match");
-
-                       int pos = 0;
-                       T[] d = Empty<T>();
-                       for (int i = 0; i < array.Length; i++) {
-                               if (match (array [i])) {
-                                       if (pos == d.Length)
-                                               Resize (ref d, pos == 0 ? 4 : pos * 2);
-
-                                       d [pos++] = array [i];
-                               }
-                       }
-
-                       if (pos != d.Length)
-                               Resize (ref d, pos);
-
-                       return d;
-               }
-
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                //
                // The constrained copy should guarantee that if there is an exception thrown
@@ -624,9 +643,40 @@ namespace System
                        Copy (sourceArray, sourceIndex, destinationArray, destinationIndex, length);
                }
 
-               object GetValueWithFlattenedIndex_NoErrorCheck (int flattenedIndex)
+               public static T[] Empty<T>()
+               {
+                       return EmptyArray<T>.Value;
+               }
+
+               public void Initialize()
+               {
+                       return;
+               }
+
+               static int IndexOfImpl<T>(T[] array, T value, int startIndex, int count)
+               {
+                       return EqualityComparer<T>.Default.IndexOf (array, value, startIndex, count);
+               }
+
+               static int LastIndexOfImpl<T>(T[] array, T value, int startIndex, int count)
+               {
+                       return EqualityComparer<T>.Default.LastIndexOf (array, value, startIndex, count);
+               }
+
+               static void SortImpl (Array keys, Array items, int index, int length, IComparer comparer)
                {
-                       return GetValueImpl (flattenedIndex);
+                       Object[] objKeys = keys as Object[];
+                       Object[] objItems = null;
+                       if (objKeys != null)
+                               objItems = items as Object[];
+
+                       if (objKeys != null && (items == null || objItems != null)) {
+                               SorterObjectArray sorter = new SorterObjectArray(objKeys, objItems, comparer);
+                               sorter.Sort(index, length);
+                       } else {
+                               SorterGenericArray sorter = new SorterGenericArray(keys, items, comparer);
+                               sorter.Sort(index, length);
+                       }
                }
 
                #region Unsafe array operations
@@ -678,5 +728,17 @@ namespace System
                                return comparison(x, y);
                        }
                }
+
+               partial class ArrayEnumerator
+               {
+                       public Object Current {
+                               get {
+                                       if (_index < 0) throw new InvalidOperationException (SR.InvalidOperation_EnumNotStarted);
+                                       if (_index >= _endIndex) throw new InvalidOperationException (SR.InvalidOperation_EnumEnded);
+                                       if (_index == 0 && _array.GetType ().GetElementType ().IsPointer) throw new NotSupportedException ("Type is not supported");
+                                       return _array.GetValueImpl(_index);
+                               }
+                       }
+               }
        }
 }