Merge branch 'master' into msbuilddll2
[mono.git] / mcs / class / corlib / System / Tuples.cs
index eeacc0d329ddac7e4f0f796a931d20602a8798fe..27604d5307ba623babaf0cd419ae2125de7eca7f 100644 (file)
@@ -57,7 +57,7 @@ namespace System
                                        ok = false;
                        }
                        if (!ok)
-                               throw new ArgumentException ("The last element of an eight element tuple must be a Tuple.");
+                               throw new ArgumentException ("rest", "The last element of an eight element tuple must be a Tuple.");
                }
        }
 
@@ -82,9 +82,15 @@ namespace System
                        return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
                }
 
-               [MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)
+               int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
-                       throw new NotImplementedException ();
+                       var t = other as Tuple<T1>;
+                       if (t == null) {
+                               if (other == null) return 1;
+                               throw new ArgumentException ("other");
+                       }
+
+                       return comparer.Compare (item1, t.item1);
                }
 
                public override bool Equals (object obj)
@@ -95,10 +101,8 @@ namespace System
                bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
                {
                        var t = other as Tuple<T1>;
-                       if (t == null) {
-                               if (other == null) return false;
-                               throw new ArgumentException ();
-                       }
+                       if (t == null)
+                               return false;
 
                        return comparer.Equals (item1, t.item1);
                }
@@ -144,9 +148,17 @@ namespace System
                        return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
                }
 
-               [MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)
+               int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
-                       throw new NotImplementedException ();
+                       var t = other as Tuple<T1, T2>;
+                       if (t == null) {
+                               if (other == null) return 1;
+                               throw new ArgumentException ("other");
+                       }
+
+                       int res = comparer.Compare (item1, t.item1);
+                       if (res != 0) return res;
+                       return comparer.Compare (item2, t.item2);
                }
 
                public override bool Equals (object obj)
@@ -157,10 +169,8 @@ namespace System
                bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
                {
                        var t = other as Tuple<T1, T2>;
-                       if (t == null) {
-                               if (other == null) return false;
-                               throw new ArgumentException ();
-                       }
+                       if (t == null)
+                               return false;
 
                        return comparer.Equals (item1, t.item1) &&
                                comparer.Equals (item2, t.item2);
@@ -173,9 +183,10 @@ namespace System
 
                int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
                {
-                       int h = comparer.GetHashCode (item1);
-                       h = (h << 5) - h + comparer.GetHashCode (item2);
-                       return h;
+                       int h0;
+                       h0 = comparer.GetHashCode (item1);
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
+                       return h0;
                }
 
                public override string ToString ()
@@ -215,9 +226,19 @@ namespace System
                        return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
                }
 
-               [MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)
+               int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
-                       throw new NotImplementedException ();
+                       var t = other as Tuple<T1, T2, T3>;
+                       if (t == null) {
+                               if (other == null) return 1;
+                               throw new ArgumentException ("other");
+                       }
+
+                       int res = comparer.Compare (item1, t.item1);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item2, t.item2);
+                       if (res != 0) return res;
+                       return comparer.Compare (item3, t.item3);
                }
 
                public override bool Equals (object obj)
@@ -228,10 +249,8 @@ namespace System
                bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
                {
                        var t = other as Tuple<T1, T2, T3>;
-                       if (t == null) {
-                               if (other == null) return false;
-                               throw new ArgumentException ();
-                       }
+                       if (t == null)
+                               return false;
 
                        return comparer.Equals (item1, t.item1) &&
                                comparer.Equals (item2, t.item2) &&
@@ -245,10 +264,11 @@ namespace System
 
                int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
                {
-                       int h = comparer.GetHashCode (item1);
-                       h = (h << 5) - h + comparer.GetHashCode (item2);
-                       h = (h << 5) - h + comparer.GetHashCode (item3);
-                       return h;
+                       int h0;
+                       h0 = comparer.GetHashCode (item1);
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item3);
+                       return h0;
                }
 
                public override string ToString ()
@@ -294,9 +314,21 @@ namespace System
                        return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
                }
 
-               [MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)
+               int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
-                       throw new NotImplementedException ();
+                       var t = other as Tuple<T1, T2, T3, T4>;
+                       if (t == null) {
+                               if (other == null) return 1;
+                               throw new ArgumentException ("other");
+                       }
+
+                       int res = comparer.Compare (item1, t.item1);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item2, t.item2);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item3, t.item3);
+                       if (res != 0) return res;
+                       return comparer.Compare (item4, t.item4);
                }
 
                public override bool Equals (object obj)
@@ -307,10 +339,8 @@ namespace System
                bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
                {
                        var t = other as Tuple<T1, T2, T3, T4>;
-                       if (t == null) {
-                               if (other == null) return false;
-                               throw new ArgumentException ();
-                       }
+                       if (t == null)
+                               return false;
 
                        return comparer.Equals (item1, t.item1) &&
                                comparer.Equals (item2, t.item2) &&
@@ -325,11 +355,13 @@ namespace System
 
                int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
                {
-                       int h = comparer.GetHashCode (item1);
-                       h = (h << 5) - h + comparer.GetHashCode (item2);
-                       h = (h << 5) - h + comparer.GetHashCode (item3);
-                       h = (h << 5) - h + comparer.GetHashCode (item4);
-                       return h;
+                       int h0, h1;
+                       h0 = comparer.GetHashCode (item1);
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
+                       h1 = comparer.GetHashCode (item3);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
+                       h0 = (h0 << 5) + h0 ^ h1;
+                       return h0;
                }
 
                public override string ToString ()
@@ -381,9 +413,23 @@ namespace System
                        return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
                }
 
-               [MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)
+               int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
-                       throw new NotImplementedException ();
+                       var t = other as Tuple<T1, T2, T3, T4, T5>;
+                       if (t == null) {
+                               if (other == null) return 1;
+                               throw new ArgumentException ("other");
+                       }
+
+                       int res = comparer.Compare (item1, t.item1);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item2, t.item2);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item3, t.item3);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item4, t.item4);
+                       if (res != 0) return res;
+                       return comparer.Compare (item5, t.item5);
                }
 
                public override bool Equals (object obj)
@@ -394,10 +440,8 @@ namespace System
                bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
                {
                        var t = other as Tuple<T1, T2, T3, T4, T5>;
-                       if (t == null) {
-                               if (other == null) return false;
-                               throw new ArgumentException ();
-                       }
+                       if (t == null)
+                               return false;
 
                        return comparer.Equals (item1, t.item1) &&
                                comparer.Equals (item2, t.item2) &&
@@ -413,12 +457,14 @@ namespace System
 
                int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
                {
-                       int h = comparer.GetHashCode (item1);
-                       h = (h << 5) - h + comparer.GetHashCode (item2);
-                       h = (h << 5) - h + comparer.GetHashCode (item3);
-                       h = (h << 5) - h + comparer.GetHashCode (item4);
-                       h = (h << 5) - h + comparer.GetHashCode (item5);
-                       return h;
+                       int h0, h1;
+                       h0 = comparer.GetHashCode (item1);
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
+                       h1 = comparer.GetHashCode (item3);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
+                       h0 = (h0 << 5) + h0 ^ h1;
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item5);
+                       return h0;
                }
 
                public override string ToString ()
@@ -476,9 +522,25 @@ namespace System
                        return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
                }
 
-               [MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)
+               int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
-                       throw new NotImplementedException ();
+                       var t = other as Tuple<T1, T2, T3, T4, T5, T6>;
+                       if (t == null) {
+                               if (other == null) return 1;
+                               throw new ArgumentException ("other");
+                       }
+
+                       int res = comparer.Compare (item1, t.item1);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item2, t.item2);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item3, t.item3);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item4, t.item4);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item5, t.item5);
+                       if (res != 0) return res;
+                       return comparer.Compare (item6, t.item6);
                }
 
                public override bool Equals (object obj)
@@ -489,10 +551,8 @@ namespace System
                bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
                {
                        var t = other as Tuple<T1, T2, T3, T4, T5, T6>;
-                       if (t == null) {
-                               if (other == null) return false;
-                               throw new ArgumentException ();
-                       }
+                       if (t == null)
+                               return false;
 
                        return comparer.Equals (item1, t.item1) &&
                                comparer.Equals (item2, t.item2) &&
@@ -509,13 +569,16 @@ namespace System
 
                int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
                {
-                       int h = comparer.GetHashCode (item1);
-                       h = (h << 5) - h + comparer.GetHashCode (item2);
-                       h = (h << 5) - h + comparer.GetHashCode (item3);
-                       h = (h << 5) - h + comparer.GetHashCode (item4);
-                       h = (h << 5) - h + comparer.GetHashCode (item5);
-                       h = (h << 5) - h + comparer.GetHashCode (item6);
-                       return h;
+                       int h0, h1;
+                       h0 = comparer.GetHashCode (item1);
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
+                       h1 = comparer.GetHashCode (item3);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
+                       h0 = (h0 << 5) + h0 ^ h1;
+                       h1 = comparer.GetHashCode (item5);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
+                       h0 = (h0 << 5) + h0 ^ h1;
+                       return h0;
                }
 
                public override string ToString ()
@@ -579,9 +642,27 @@ namespace System
                        return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
                }
 
-               [MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)
+               int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
-                       throw new NotImplementedException ();
+                       var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
+                       if (t == null) {
+                               if (other == null) return 1;
+                               throw new ArgumentException ("other");
+                       }
+
+                       int res = comparer.Compare (item1, t.item1);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item2, t.item2);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item3, t.item3);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item4, t.item4);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item5, t.item5);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item6, t.item6);
+                       if (res != 0) return res;
+                       return comparer.Compare (item7, t.item7);
                }
 
                public override bool Equals (object obj)
@@ -592,10 +673,8 @@ namespace System
                bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
                {
                        var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
-                       if (t == null) {
-                               if (other == null) return false;
-                               throw new ArgumentException ();
-                       }
+                       if (t == null)
+                               return false;
 
                        return comparer.Equals (item1, t.item1) &&
                                comparer.Equals (item2, t.item2) &&
@@ -613,14 +692,17 @@ namespace System
 
                int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
                {
-                       int h = comparer.GetHashCode (item1);
-                       h = (h << 5) - h + comparer.GetHashCode (item2);
-                       h = (h << 5) - h + comparer.GetHashCode (item3);
-                       h = (h << 5) - h + comparer.GetHashCode (item4);
-                       h = (h << 5) - h + comparer.GetHashCode (item5);
-                       h = (h << 5) - h + comparer.GetHashCode (item6);
-                       h = (h << 5) - h + comparer.GetHashCode (item7);
-                       return h;
+                       int h0, h1;
+                       h0 = comparer.GetHashCode (item1);
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
+                       h1 = comparer.GetHashCode (item3);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
+                       h0 = (h0 << 5) + h0 ^ h1;
+                       h1 = comparer.GetHashCode (item5);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item7);
+                       h0 = (h0 << 5) + h0 ^ h1;
+                       return h0;
                }
 
                public override string ToString ()
@@ -678,9 +760,29 @@ namespace System
                        return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
                }
 
-               [MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)
+               int IStructuralComparable.CompareTo (object other, IComparer comparer)
                {
-                       throw new NotImplementedException ();
+                       var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>;
+                       if (t == null) {
+                               if (other == null) return 1;
+                               throw new ArgumentException ("other");
+                       }
+
+                       int res = comparer.Compare (item1, t.item1);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item2, t.item2);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item3, t.item3);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item4, t.item4);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item5, t.item5);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item6, t.item6);
+                       if (res != 0) return res;
+                       res = comparer.Compare (item7, t.item7);
+                       if (res != 0) return res;
+                       return comparer.Compare (rest, t.rest);
                }
 
                public override bool Equals (object obj)
@@ -691,10 +793,8 @@ namespace System
                bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
                {
                        var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>;
-                       if (t == null) {
-                               if (other == null) return false;
-                               throw new ArgumentException ();
-                       }
+                       if (t == null)
+                               return false;
 
                        return comparer.Equals (item1, t.item1) &&
                                comparer.Equals (item2, t.item2) &&
@@ -713,15 +813,19 @@ namespace System
 
                int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
                {
-                       int h = comparer.GetHashCode (item1);
-                       h = (h << 5) - h + comparer.GetHashCode (item2);
-                       h = (h << 5) - h + comparer.GetHashCode (item3);
-                       h = (h << 5) - h + comparer.GetHashCode (item4);
-                       h = (h << 5) - h + comparer.GetHashCode (item5);
-                       h = (h << 5) - h + comparer.GetHashCode (item6);
-                       h = (h << 5) - h + comparer.GetHashCode (item7);
-                       h = (h << 5) - h + comparer.GetHashCode (rest);
-                       return h;
+                       int h0, h1, h2;
+                       h0 = comparer.GetHashCode (item1);
+                       h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
+                       h1 = comparer.GetHashCode (item3);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
+                       h0 = (h0 << 5) + h0 ^ h1;
+                       h1 = comparer.GetHashCode (item5);
+                       h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
+                       h2 = comparer.GetHashCode (item7);
+                       h2 = (h2 << 5) + h2 ^ comparer.GetHashCode (rest);
+                       h1 = (h1 << 5) + h1 ^ h2;
+                       h0 = (h0 << 5) + h0 ^ h1;
+                       return h0;
                }
 
                public override string ToString ()
@@ -788,10 +892,25 @@ public class TupleGen
                        Console.WriteLine ("\t\t}");
                        
                        Console.WriteLine ();
-                       Console.WriteLine ("\t\t[MonoTODO] int IStructuralComparable.CompareTo (object other, IComparer comparer)");
+                       Console.WriteLine ("\t\tint IStructuralComparable.CompareTo (object other, IComparer comparer)");
                        Console.WriteLine ("\t\t{");
-                       Console.WriteLine ("\t\t\tthrow new NotImplementedException ();");
-                       Console.WriteLine ("\t\t}");
+                       Console.WriteLine ("\t\t\tvar t = other as {0};", type_name);
+                       Console.WriteLine ("\t\t\tif (t == null) {");
+                       Console.WriteLine ("\t\t\t\tif (other == null) return 1;");
+                       Console.WriteLine ("\t\t\t\tthrow new ArgumentException (\"other\");");
+                       Console.WriteLine ("\t\t\t}");
+                       Console.WriteLine ();
+                       
+                       for (int i = 1; i < arity; ++i) {
+                               Console.Write ("\t\t\t");
+                               if (i == 1)
+                                       Console.Write ("int ");
+
+                               Console.WriteLine ("res = comparer.Compare ({0}, t.{0});", GetItemName (i));
+                               Console.WriteLine ("\t\t\tif (res != 0) return res;");
+                       }
+                       Console.WriteLine ("\t\t\treturn comparer.Compare ({0}, t.{0});", GetItemName (arity));
+                       Console.WriteLine ("\t\t}");                    
                        
                        Console.WriteLine ();
                        Console.WriteLine ("\t\tpublic override bool Equals (object obj)");
@@ -803,10 +922,8 @@ public class TupleGen
                        Console.WriteLine ("\t\tbool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)");
                        Console.WriteLine ("\t\t{");
                        Console.WriteLine ("\t\t\tvar t = other as {0};", type_name);
-                       Console.WriteLine ("\t\t\tif (t == null) {");
-                       Console.WriteLine ("\t\t\t\tif (other == null) return false;");
-                       Console.WriteLine ("\t\t\t\tthrow new ArgumentException ();");
-                       Console.WriteLine ("\t\t\t}");
+                       Console.WriteLine ("\t\t\tif (t == null)");
+                       Console.WriteLine ("\t\t\t\treturn false;");
                        Console.WriteLine ();
                        Console.Write ("\t\t\treturn");
                        
@@ -827,7 +944,7 @@ public class TupleGen
                        Console.WriteLine ();
                        Console.WriteLine ("\t\tpublic override int GetHashCode ()");
                        Console.WriteLine ("\t\t{");
-                       Console.WriteLine ("\t\t\treturn GetHashCode (EqualityComparer<object>.Default);");
+                       Console.WriteLine ("\t\t\treturn ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);");
                        Console.WriteLine ("\t\t}");
                        
                        Console.WriteLine ();
@@ -836,10 +953,15 @@ public class TupleGen
                        if (arity == 1) {
                                Console.WriteLine ("\t\t\treturn comparer.GetHashCode ({0});", GetItemName (arity));
                        } else {
-                               Console.WriteLine ("\t\t\tint h = comparer.GetHashCode ({0});", GetItemName (1));
-                               for (int i = 2; i <= arity; ++i)
-                                       Console.WriteLine ("\t\t\th = (h << 5) - h + comparer.GetHashCode ({0});", GetItemName (i));
-                               Console.WriteLine ("\t\t\treturn h;");
+                               int varnum = IntLog2(arity);
+                               Console.Write ("\t\t\tint h0");
+                               for (int i = 1; i < varnum; ++i)
+                                       Console.Write (", h{0}", i);
+                               Console.WriteLine (";");
+
+                               WriteHash(0, 1, arity);
+
+                               Console.WriteLine ("\t\t\treturn h0;");
                        }
 
                        Console.WriteLine ("\t\t}");
@@ -866,6 +988,36 @@ public class TupleGen
                }
        }
 
+       static int IntLog2 (int n)
+       {
+               int r = -1;
+
+               while (n != 0) {
+                       n >>= 1;
+                       r++;
+               }
+
+               return r;
+       }
+
+       static void WriteHash (int destVar, int start, int count)
+       {
+               if (count == 1) {
+                       Console.WriteLine ("\t\t\th{0} = comparer.GetHashCode ({1});", destVar, GetItemName (start));
+               } else {
+                       int subCount = 1 << IntLog2(count-1);
+                       computeHash(destVar, start, subCount);
+                       start += subCount;
+                       count -= subCount;
+                       if (count == 1) {
+                               Console.WriteLine ("\t\t\th{0} = (h{0} << 5) + h{0} ^ comparer.GetHashCode ({1});", destVar, GetItemName (start));
+                       } else {
+                               WriteHash(destVar+1, start, count);
+                               Console.WriteLine ("\t\t\th{0} = (h{0} << 5) + h{0} ^ h{1};", destVar, destVar+1);
+                       }
+               }
+       }
+
        static string GetTypeName (int arity)
        {
                StringBuilder sb = new StringBuilder ();