[corlib] Port more of corert array
authorMarek Safar <marek.safar@gmail.com>
Wed, 29 Mar 2017 13:43:32 +0000 (15:43 +0200)
committerMarek Safar <marek.safar@gmail.com>
Tue, 4 Apr 2017 06:40:42 +0000 (08:40 +0200)
mcs/class/corlib/System/Array.cs
mcs/class/corlib/corert/Array.Portable.cs

index 91b3709e63f41f430c71bc1e8bd29bbdb12cf979..946647ae149da3a979b204fbb60b6fb4a704e051 100644 (file)
@@ -40,9 +40,6 @@ using System.Runtime.InteropServices;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Runtime.ConstrainedExecution;
-#if !FULL_AOT_RUNTIME
-using System.Reflection.Emit;
-#endif
 
 namespace System
 {
@@ -114,45 +111,9 @@ namespace System
                        return false;
                }
 
-               int IList.IndexOf (object value)
+               internal void InternalArray__ICollection_CopyTo<T> (T[] array, int arrayIndex)
                {
-                       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++) {
-                               if (Object.Equals (this.GetValueImpl (i), value))
-                                       // array index may not be zero-based.
-                                       // use lower bound
-                                       return i + this.GetLowerBound (0);
-                       }
-
-                       unchecked {
-                               // lower bound may be MinValue
-                               return this.GetLowerBound (0) - 1;
-                       }
-               }
-
-               internal 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));
+                       Copy (this, GetLowerBound (0), array, arrayIndex, Length);
                }
 
                internal T InternalArray__IReadOnlyList_get_Item<T> (int index)
@@ -342,12 +303,6 @@ namespace System
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal extern static Array CreateInstanceImpl (Type elementType, int[] lengths, int[] bounds);
 
-               public bool IsReadOnly {
-                       get {
-                               return false;
-                       }
-               }
-
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                public int GetUpperBound (int dimension)
                {
@@ -377,50 +332,6 @@ namespace System
                        return GetValue (ind);
                }
 
-               [ComVisible (false)]
-               public void SetValue (object value, long index)
-               {
-                       if (index < 0 || index > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       SetValue (value, (int) index);
-               }
-
-               [ComVisible (false)]
-               public void SetValue (object value, long index1, long index2)
-               {
-                       if (index1 < 0 || index1 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index1", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       if (index2 < 0 || index2 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index2", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       int[] ind = {(int) index1, (int) index2};
-                       SetValue (value, ind);
-               }
-
-               [ComVisible (false)]
-               public void SetValue (object value, long index1, long index2, long index3)
-               {
-                       if (index1 < 0 || index1 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index1", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       if (index2 < 0 || index2 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index2", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       if (index3 < 0 || index3 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index3", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       int[] ind = {(int) index1, (int) index2, (int) index3};
-                       SetValue (value, ind);
-               }
-
                public void SetValue (object value, int index)
                {
                        if (Rank != 1)
@@ -499,10 +410,6 @@ namespace System
                                throw new NotSupportedException ("Array type can not be void");
                        if (elementType.ContainsGenericParameters)
                                throw new NotSupportedException ("Array type can not be an open generic type");
-#if !FULL_AOT_RUNTIME
-                       if ((elementType is TypeBuilder) && !(elementType as TypeBuilder).IsCreated ())
-                               throw new NotSupportedException ("Can't create an array of the unfinished type '" + elementType + "'.");
-#endif
                        
                        return CreateInstanceImpl (elementType, lengths, bounds);
                }
@@ -545,36 +452,6 @@ namespace System
                        return CreateInstanceImpl (elementType, lengths, lowerBounds);
                }
 
-               static int [] GetIntArray (long [] values)
-               {
-                       int len = values.Length;
-                       int [] ints = new int [len];
-                       for (int i = 0; i < len; i++) {
-                               long current = values [i];
-                               if (current < 0 || current > (long) Int32.MaxValue)
-                                       throw new ArgumentOutOfRangeException ("values", Locale.GetText (
-                                               "Each value has to be >= 0 and <= Int32.MaxValue."));
-
-                               ints [i] = (int) current;
-                       }
-                       return ints;
-               }
-
-               public static Array CreateInstance (Type elementType, params long [] lengths)
-               {
-                       if (lengths == null)
-                               throw new ArgumentNullException ("lengths");
-                       return CreateInstance (elementType, GetIntArray (lengths));
-               }
-
-               [ComVisible (false)]
-               public void SetValue (object value, params long [] indices)
-               {
-                       if (indices == null)
-                               throw new ArgumentNullException ("indices");
-                       SetValue (value, GetIntArray (indices));
-               }
-
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                public static void Clear (Array array, int index, int length)
                {
@@ -712,7 +589,7 @@ namespace System
                        return source.IsAssignableFrom (target) || target.IsAssignableFrom (source);
                }
 
-               public static T [] FindAll<T> (T [] array, Predicate <T> match)
+               public static T[] FindAll<T> (T[] array, Predicate<T> match)
                {
                        if (array == null)
                                throw new ArgumentNullException ("array");
@@ -721,12 +598,19 @@ namespace System
                                throw new ArgumentNullException ("match");
 
                        int pos = 0;
-                       T [] d = new T [array.Length];
-                       foreach (T t in array)
-                               if (match (t))
-                                       d [pos++] = t;
+                       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);
 
-                       Resize <T> (ref d, pos);
                        return d;
                }
 
index 7eb3bc08918c58c05a5f4291af4b338edd555e3b..96e4ee325f41cb8cb7d6fa93342a7df8fab58fff 100644 (file)
@@ -19,6 +19,26 @@ namespace System
 {
     public abstract partial class Array : ICollection, IEnumerable, IList, IStructuralComparable, IStructuralEquatable, ICloneable
     {
+        public static Array CreateInstance(Type elementType, params long[] lengths)
+        {
+            if (lengths == null)
+                throw new ArgumentNullException(nameof(lengths));
+            if (lengths.Length == 0)
+                throw new ArgumentException(SR.Arg_NeedAtLeast1Rank);
+
+            int[] intLengths = new int[lengths.Length];
+
+            for (int i = 0; i < lengths.Length; ++i)
+            {
+                long len = lengths[i];
+                if (len > int.MaxValue || len < int.MinValue)
+                    throw new ArgumentOutOfRangeException("len", SR.ArgumentOutOfRange_HugeArrayNotSupported);
+                intLengths[i] = (int)len;
+            }
+
+            return Array.CreateInstance(elementType, intLengths);
+        }
+
         public static ReadOnlyCollection<T> AsReadOnly<T>(T[] array)
         {
             if (array == null)
@@ -83,7 +103,12 @@ namespace System
 
         void IList.Clear()
         {
-            Array.Clear(this, 0, this.Length);
+            Array.Clear(this, GetLowerBound(0), this.Length);
+        }
+
+        int IList.IndexOf(Object value)
+        {
+            return Array.IndexOf(this, value);
         }
 
         void IList.Insert(int index, Object value)
@@ -114,7 +139,7 @@ namespace System
             if (array != null && array.Rank != 1)
                 throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
 
-            Array.Copy(this, 0, array, index, Length);
+            Array.Copy(this, GetLowerBound(0), array, index, Length);
         }
 
         // Make a new array which is a deep copy of the original array.
@@ -226,7 +251,7 @@ namespace System
         {
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
-            return BinarySearch(array, 0, array.Length, value, null);
+            return BinarySearch(array, array.GetLowerBound(0), array.Length, value, null);
         }
 
         public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput, TOutput> converter)
@@ -380,6 +405,8 @@ namespace System
 
         public bool IsFixedSize { get { return true; } }
 
+        public bool IsReadOnly { get { return false; } }
+
         // Is this Array synchronized (i.e., thread-safe)?  If you want a synchronized
         // collection, you can use SyncRoot as an object to synchronize your 
         // collection with.  You could also call GetSynchronized() 
@@ -426,7 +453,7 @@ namespace System
         {
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
-            return BinarySearch(array, 0, array.Length, value, comparer);
+            return BinarySearch(array, array.GetLowerBound(0), array.Length, value, comparer);
         }
 
         // Searches a section of an array for a given element using a binary search
@@ -565,7 +592,7 @@ namespace System
                 throw new ArgumentNullException(nameof(array));
             }
 
-            return IndexOf(array, value, 0, array.Length);
+            return IndexOf(array, value, array.GetLowerBound(0), array.Length);
         }
 
         // Returns the index of the first occurrence of a given value in a range of
@@ -581,7 +608,8 @@ namespace System
                 throw new ArgumentNullException(nameof(array));
             }
 
-            return IndexOf(array, value, startIndex, array.Length - startIndex);
+            int lb = array.GetLowerBound(0);
+            return IndexOf(array, value, startIndex, array.Length - startIndex + lb);
         }
 
         // Returns the index of the first occurrence of a given value in a range of
@@ -596,9 +624,10 @@ namespace System
                 throw new ArgumentNullException(nameof(array));
             if (array.Rank != 1)
                 throw new RankException(SR.Rank_MultiDimNotSupported);
-            if (startIndex < 0 || startIndex > array.Length)
+            int lb = array.GetLowerBound(0);
+            if (startIndex < lb || startIndex > array.Length + lb)
                 throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
-            if (count < 0 || count > array.Length - startIndex)
+            if (count < 0 || count > array.Length - startIndex + lb)
                 throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
 
             Object[] objArray = array as Object[];
@@ -636,7 +665,7 @@ namespace System
                     }
                 }
             }
-            return -1;
+            return lb - 1;
         }
 
         /// <summary>
@@ -903,7 +932,7 @@ namespace System
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
 
-            Reverse(array, 0, array.Length);
+            Reverse(array, array.GetLowerBound(0), array.Length);
         }
 
         // Reverses the elements in a range of an array. Following a call to this
@@ -980,6 +1009,56 @@ namespace System
             }
         }
 
+        public void SetValue(object value, long index)
+        {
+            if (index > int.MaxValue || index < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+
+            SetValue(value, (int)index);
+        }
+
+        public void SetValue(object value, long index1, long index2)
+        {
+            if (index1 > int.MaxValue || index1 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index1), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+            if (index2 > int.MaxValue || index2 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index2), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+
+            SetValue(value, (int)index1, (int)index2);
+        }
+
+        public void SetValue(object value, long index1, long index2, long index3)
+        {
+            if (index1 > int.MaxValue || index1 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index1), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+            if (index2 > int.MaxValue || index2 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index2), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+            if (index3 > int.MaxValue || index3 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index3), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+
+            SetValue(value, (int)index1, (int)index2, (int)index3);
+        }
+
+        public void SetValue(object value, params long[] indices)
+        {
+            if (indices == null)
+                throw new ArgumentNullException(nameof(indices));
+            if (Rank != indices.Length)
+                throw new ArgumentException(SR.Arg_RankIndices);
+
+            int[] intIndices = new int[indices.Length];
+
+            for (int i = 0; i < indices.Length; ++i)
+            {
+                long index = indices[i];
+                if (index > int.MaxValue || index < int.MinValue)
+                    throw new ArgumentOutOfRangeException("index", SR.ArgumentOutOfRange_HugeArrayNotSupported);
+                intIndices[i] = (int)index;
+            }
+
+            SetValue(value, intIndices);
+        }
+
         // Sorts the elements of an array. The sort compares the elements to each
         // other using the IComparable interface, which must be implemented
         // by all elements of the array.
@@ -989,7 +1068,7 @@ namespace System
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
 
-            Sort(array, null, 0, array.Length, null);
+            Sort(array, null, array.GetLowerBound(0), array.Length, null);
         }
 
         // Sorts the elements in a section of an array. The sort compares the
@@ -1012,7 +1091,7 @@ namespace System
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
 
-            Sort(array, null, 0, array.Length, comparer);
+            Sort(array, null, array.GetLowerBound(0), array.Length, comparer);
         }
 
         // Sorts the elements in a section of an array. The sort compares the