Merge pull request #3662 from henricm/fix-windowsbase-on-win
[mono.git] / mcs / class / corlib / System / Array.cs
index 519b8d1a09a4d649aeedf51e9275ef2bb8edcd91..8f6e0aa098e40b238d2738503705207086c3eb80 100644 (file)
@@ -50,9 +50,7 @@ namespace System
        [ComVisible (true)]
        // FIXME: We are doing way to many double/triple exception checks for the overloaded functions"
        public abstract class Array : ICloneable, ICollection, IList, IEnumerable
-#if NET_4_0
                , IStructuralComparable, IStructuralEquatable
-#endif
        {
                // Constructor
                private Array ()
@@ -142,7 +140,6 @@ namespace System
                        Copy (this, this.GetLowerBound (0), array, index, this.GetLength (0));
                }
 
-#if NET_4_5
                internal T InternalArray__IReadOnlyList_get_Item<T> (int index)
                {
                        if (unchecked ((uint) index) >= unchecked ((uint) Length))
@@ -157,7 +154,6 @@ namespace System
                {
                        return Length;
                }
-#endif
 
                internal void InternalArray__Insert<T> (int index, T item)
                {
@@ -455,7 +451,6 @@ namespace System
                        return new SimpleEnumerator (this);
                }
 
-#if NET_4_0
                int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
                        if (other == null)
@@ -514,7 +509,6 @@ namespace System
                                hash = ((hash << 7) + hash) ^ comparer.GetHashCode (GetValueImpl (i));
                        return hash;
                }
-#endif
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                public int GetUpperBound (int dimension)
@@ -654,6 +648,26 @@ namespace System
                        SetValue (value, ind);
                }
 
+               internal static Array UnsafeCreateInstance (Type elementType, int length)
+               {
+                       return CreateInstance (elementType, length);
+               }
+
+               internal static Array UnsafeCreateInstance(Type elementType, int[] lengths, int[] lowerBounds)
+               {
+                       return CreateInstance(elementType, lengths, lowerBounds);
+               }
+
+               internal static Array UnsafeCreateInstance (Type elementType, int length1, int length2)
+               {
+                       return CreateInstance (elementType, length1, length2);
+               }
+
+               internal static Array UnsafeCreateInstance (Type elementType, params int[] lengths)
+               {
+                       return CreateInstance(elementType, lengths);
+               }
+
                public static Array CreateInstance (Type elementType, int length)
                {
                        int[] lengths = {length};
@@ -687,8 +701,8 @@ namespace System
 
                        int[] bounds = null;
 
-                       elementType = elementType.UnderlyingSystemType;
-                       if (!elementType.IsSystemType)
+                       elementType = elementType.UnderlyingSystemType as RuntimeType;
+                       if (elementType == null)
                                throw new ArgumentException ("Type must be a type provided by the runtime.", "elementType");
                        if (elementType.Equals (typeof (void)))
                                throw new NotSupportedException ("Array type can not be void");
@@ -711,8 +725,8 @@ namespace System
                        if (lowerBounds == null)
                                throw new ArgumentNullException ("lowerBounds");
 
-                       elementType = elementType.UnderlyingSystemType;
-                       if (!elementType.IsSystemType)
+                       elementType = elementType.UnderlyingSystemType as RuntimeType;
+                       if (elementType == null)
                                throw new ArgumentException ("Type must be a type provided by the runtime.", "elementType");
                        if (elementType.Equals (typeof (void)))
                                throw new NotSupportedException ("Array type can not be void");
@@ -934,6 +948,9 @@ namespace System
                        int source_pos = sourceIndex - sourceArray.GetLowerBound (0);
                        int dest_pos = destinationIndex - destinationArray.GetLowerBound (0);
 
+                       if (dest_pos < 0)
+                               throw new ArgumentOutOfRangeException ("destinationIndex", "Index was less than the array's lower bound in the first dimension.");
+
                        // re-ordered to avoid possible integer overflow
                        if (source_pos > sourceArray.Length - length)
                                throw new ArgumentException ("length");
@@ -1005,7 +1022,7 @@ namespace System
 
                [ReliabilityContractAttribute (Consistency.MayCorruptInstance, Cer.MayFail)]
                public static void Copy (Array sourceArray, long sourceIndex, Array destinationArray,
-                                        long destinationIndex, long length)
+                                                                long destinationIndex, long length)
                {
                        if (sourceArray == null)
                                throw new ArgumentNullException ("sourceArray");
@@ -1672,10 +1689,10 @@ namespace System
                
                        if (keys == null)
                                throw new ArgumentNullException ("keys");
-                               
-                       if (keys.Length != items.Length)
-                               throw new ArgumentException ("Length of keys and items does not match.");
-                       
+
+                       if (keys.Length > items.Length)
+                               throw new ArgumentException ("Length of keys is larger than length of items.");
+
                        SortImpl<TKey, TValue> (keys, items, 0, keys.Length, comparer);
                }
 
@@ -2727,7 +2744,7 @@ namespace System
 
                        public object Current {
                                get {
-                                       // Exception messages based on MS implementation
+                                       // Exception messages based on MS implementation
                                        if (currentpos < 0 )
                                                throw new InvalidOperationException (Locale.GetText (
                                                        "Enumeration has not started."));
@@ -3028,7 +3045,7 @@ namespace System
                        if (count < 0 || startIndex < array.GetLowerBound (0) || startIndex - 1 > array.GetUpperBound (0) - count)
                                throw new ArgumentOutOfRangeException ();
 
-                       return EqualityComparer<T>.Default.IndexOf (array, value, startIndex, startIndex + count);
+                       return EqualityComparer<T>.Default.IndexOf (array, value, startIndex, count);
                }
                
                public static int LastIndexOf<T> (T [] array, T value)
@@ -3085,6 +3102,12 @@ namespace System
                        return d;
                }
 
+               [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+               public static T[] Empty<T>()
+               {
+                       return EmptyArray<T>.Value;
+               }
+
                public static bool Exists<T> (T [] array, Predicate <T> match)
                {
                        if (array == null)
@@ -3166,10 +3189,35 @@ namespace System
                //
                // Moved value from instance into target of different type with no checks (JIT intristics)
                //
+               // Restrictions:
+               //
+               // S and R must either:
+               //       both be blitable valuetypes
+               //       both be reference types (IOW, an unsafe cast)
+               // S and R cannot be float or double
+               // S and R must either:
+               //       both be a struct
+               //       both be a scalar
+               // S and R must either:
+               //       be of same size
+               //       both be a scalar of size <= 4
+               //
                internal static R UnsafeMov<S,R> (S instance) {
                        return (R)(object) instance;
                }
 
                #endregion
+
+               internal sealed class FunctorComparer<T> : IComparer<T> {
+                       Comparison<T> comparison;
+
+                       public FunctorComparer(Comparison<T> comparison) {
+                               this.comparison = comparison;
+                       }
+
+                       public int Compare(T x, T y) {
+                               return comparison(x, y);
+                       }
+               }
        }
 }