// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Text; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; // // Note: F# compiler depends on the exact tuple hashing algorithm. Do not ever change it. // namespace System { /// /// Helper so we can call some tuple methods recursively without knowing the underlying types. /// internal interface ITupleInternal : ITuple { string ToString(StringBuilder sb); int GetHashCode(IEqualityComparer comparer); } public static class Tuple { public static Tuple Create(T1 item1) { return new Tuple(item1); } public static Tuple Create(T1 item1, T2 item2) { return new Tuple(item1, item2); } public static Tuple Create(T1 item1, T2 item2, T3 item3) { return new Tuple(item1, item2, item3); } public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4) { return new Tuple(item1, item2, item3, item4); } public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { return new Tuple(item1, item2, item3, item4, item5); } public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { return new Tuple(item1, item2, item3, item4, item5, item6); } public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { return new Tuple(item1, item2, item3, item4, item5, item6, item7); } public static Tuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { return new Tuple>(item1, item2, item3, item4, item5, item6, item7, new Tuple(item8)); } // From System.Web.Util.HashCodeCombiner internal static int CombineHashCodes(int h1, int h2) { return (((h1 << 5) + h1) ^ h2); } internal static int CombineHashCodes(int h1, int h2, int h3) { return CombineHashCodes(CombineHashCodes(h1, h2), h3); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4) { return CombineHashCodes(CombineHashCodes(h1, h2), CombineHashCodes(h3, h4)); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) { return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), h5); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) { return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6)); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) { return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7)); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) { return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8)); } } [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { private readonly T1 m_Item1; public T1 Item1 { get { return m_Item1; } } public Tuple(T1 item1) { m_Item1 = item1; } public override Boolean Equals(Object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); } Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { if (other == null) return false; Tuple objTuple = other as Tuple; if (objTuple == null) { return false; } return comparer.Equals(m_Item1, objTuple.m_Item1); } Int32 IComparable.CompareTo(Object obj) { return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); } Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { if (other == null) return 1; Tuple objTuple = other as Tuple; if (objTuple == null) { throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other"); } return comparer.Compare(m_Item1, objTuple.m_Item1); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return comparer.GetHashCode(m_Item1); } Int32 ITupleInternal.GetHashCode(IEqualityComparer comparer) { return ((IStructuralEquatable)this).GetHashCode(comparer); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); return ((ITupleInternal)this).ToString(sb); } string ITupleInternal.ToString(StringBuilder sb) { sb.Append(m_Item1); sb.Append(")"); return sb.ToString(); } /// /// The number of positions in this data structure. /// int ITuple.Length => 1; /// /// Get the element at position . /// object ITuple.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return Item1; } } } [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { private readonly T1 m_Item1; private readonly T2 m_Item2; public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } public Tuple(T1 item1, T2 item2) { m_Item1 = item1; m_Item2 = item2; } public override Boolean Equals(Object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); ; } Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { if (other == null) return false; Tuple objTuple = other as Tuple; if (objTuple == null) { return false; } return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2); } Int32 IComparable.CompareTo(Object obj) { return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); } Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { if (other == null) return 1; Tuple objTuple = other as Tuple; if (objTuple == null) { throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other"); } int c = 0; c = comparer.Compare(m_Item1, objTuple.m_Item1); if (c != 0) return c; return comparer.Compare(m_Item2, objTuple.m_Item2); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2)); } Int32 ITupleInternal.GetHashCode(IEqualityComparer comparer) { return ((IStructuralEquatable)this).GetHashCode(comparer); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); return ((ITupleInternal)this).ToString(sb); } string ITupleInternal.ToString(StringBuilder sb) { sb.Append(m_Item1); sb.Append(", "); sb.Append(m_Item2); sb.Append(")"); return sb.ToString(); } /// /// The number of positions in this data structure. /// int ITuple.Length => 2; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; default: throw new IndexOutOfRangeException(); } } } } [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { private readonly T1 m_Item1; private readonly T2 m_Item2; private readonly T3 m_Item3; public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } public T3 Item3 { get { return m_Item3; } } public Tuple(T1 item1, T2 item2, T3 item3) { m_Item1 = item1; m_Item2 = item2; m_Item3 = item3; } public override Boolean Equals(Object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); ; } Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { if (other == null) return false; Tuple objTuple = other as Tuple; if (objTuple == null) { return false; } return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3); } Int32 IComparable.CompareTo(Object obj) { return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); } Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { if (other == null) return 1; Tuple objTuple = other as Tuple; if (objTuple == null) { throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other"); } int c = 0; c = comparer.Compare(m_Item1, objTuple.m_Item1); if (c != 0) return c; c = comparer.Compare(m_Item2, objTuple.m_Item2); if (c != 0) return c; return comparer.Compare(m_Item3, objTuple.m_Item3); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3)); } Int32 ITupleInternal.GetHashCode(IEqualityComparer comparer) { return ((IStructuralEquatable)this).GetHashCode(comparer); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); return ((ITupleInternal)this).ToString(sb); } string ITupleInternal.ToString(StringBuilder sb) { sb.Append(m_Item1); sb.Append(", "); sb.Append(m_Item2); sb.Append(", "); sb.Append(m_Item3); sb.Append(")"); return sb.ToString(); } /// /// The number of positions in this data structure. /// int ITuple.Length => 3; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; default: throw new IndexOutOfRangeException(); } } } } [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { private readonly T1 m_Item1; private readonly T2 m_Item2; private readonly T3 m_Item3; private readonly T4 m_Item4; public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } public T3 Item3 { get { return m_Item3; } } public T4 Item4 { get { return m_Item4; } } public Tuple(T1 item1, T2 item2, T3 item3, T4 item4) { m_Item1 = item1; m_Item2 = item2; m_Item3 = item3; m_Item4 = item4; } public override Boolean Equals(Object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); ; } Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { if (other == null) return false; Tuple objTuple = other as Tuple; if (objTuple == null) { return false; } return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4); } Int32 IComparable.CompareTo(Object obj) { return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); } Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { if (other == null) return 1; Tuple objTuple = other as Tuple; if (objTuple == null) { throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other"); } int c = 0; c = comparer.Compare(m_Item1, objTuple.m_Item1); if (c != 0) return c; c = comparer.Compare(m_Item2, objTuple.m_Item2); if (c != 0) return c; c = comparer.Compare(m_Item3, objTuple.m_Item3); if (c != 0) return c; return comparer.Compare(m_Item4, objTuple.m_Item4); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4)); } Int32 ITupleInternal.GetHashCode(IEqualityComparer comparer) { return ((IStructuralEquatable)this).GetHashCode(comparer); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); return ((ITupleInternal)this).ToString(sb); } string ITupleInternal.ToString(StringBuilder sb) { sb.Append(m_Item1); sb.Append(", "); sb.Append(m_Item2); sb.Append(", "); sb.Append(m_Item3); sb.Append(", "); sb.Append(m_Item4); sb.Append(")"); return sb.ToString(); } /// /// The number of positions in this data structure. /// int ITuple.Length => 4; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; default: throw new IndexOutOfRangeException(); } } } } [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { private readonly T1 m_Item1; private readonly T2 m_Item2; private readonly T3 m_Item3; private readonly T4 m_Item4; private readonly T5 m_Item5; public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } public T3 Item3 { get { return m_Item3; } } public T4 Item4 { get { return m_Item4; } } public T5 Item5 { get { return m_Item5; } } public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { m_Item1 = item1; m_Item2 = item2; m_Item3 = item3; m_Item4 = item4; m_Item5 = item5; } public override Boolean Equals(Object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); ; } Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { if (other == null) return false; Tuple objTuple = other as Tuple; if (objTuple == null) { return false; } return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4) && comparer.Equals(m_Item5, objTuple.m_Item5); } Int32 IComparable.CompareTo(Object obj) { return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); } Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { if (other == null) return 1; Tuple objTuple = other as Tuple; if (objTuple == null) { throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other"); } int c = 0; c = comparer.Compare(m_Item1, objTuple.m_Item1); if (c != 0) return c; c = comparer.Compare(m_Item2, objTuple.m_Item2); if (c != 0) return c; c = comparer.Compare(m_Item3, objTuple.m_Item3); if (c != 0) return c; c = comparer.Compare(m_Item4, objTuple.m_Item4); if (c != 0) return c; return comparer.Compare(m_Item5, objTuple.m_Item5); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5)); } Int32 ITupleInternal.GetHashCode(IEqualityComparer comparer) { return ((IStructuralEquatable)this).GetHashCode(comparer); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); return ((ITupleInternal)this).ToString(sb); } string ITupleInternal.ToString(StringBuilder sb) { sb.Append(m_Item1); sb.Append(", "); sb.Append(m_Item2); sb.Append(", "); sb.Append(m_Item3); sb.Append(", "); sb.Append(m_Item4); sb.Append(", "); sb.Append(m_Item5); sb.Append(")"); return sb.ToString(); } /// /// The number of positions in this data structure. /// int ITuple.Length => 5; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; case 4: return Item5; default: throw new IndexOutOfRangeException(); } } } } [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { private readonly T1 m_Item1; private readonly T2 m_Item2; private readonly T3 m_Item3; private readonly T4 m_Item4; private readonly T5 m_Item5; private readonly T6 m_Item6; public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } public T3 Item3 { get { return m_Item3; } } public T4 Item4 { get { return m_Item4; } } public T5 Item5 { get { return m_Item5; } } public T6 Item6 { get { return m_Item6; } } public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { m_Item1 = item1; m_Item2 = item2; m_Item3 = item3; m_Item4 = item4; m_Item5 = item5; m_Item6 = item6; } public override Boolean Equals(Object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); ; } Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { if (other == null) return false; Tuple objTuple = other as Tuple; if (objTuple == null) { return false; } return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4) && comparer.Equals(m_Item5, objTuple.m_Item5) && comparer.Equals(m_Item6, objTuple.m_Item6); } Int32 IComparable.CompareTo(Object obj) { return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); } Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { if (other == null) return 1; Tuple objTuple = other as Tuple; if (objTuple == null) { throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other"); } int c = 0; c = comparer.Compare(m_Item1, objTuple.m_Item1); if (c != 0) return c; c = comparer.Compare(m_Item2, objTuple.m_Item2); if (c != 0) return c; c = comparer.Compare(m_Item3, objTuple.m_Item3); if (c != 0) return c; c = comparer.Compare(m_Item4, objTuple.m_Item4); if (c != 0) return c; c = comparer.Compare(m_Item5, objTuple.m_Item5); if (c != 0) return c; return comparer.Compare(m_Item6, objTuple.m_Item6); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6)); } Int32 ITupleInternal.GetHashCode(IEqualityComparer comparer) { return ((IStructuralEquatable)this).GetHashCode(comparer); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); return ((ITupleInternal)this).ToString(sb); } string ITupleInternal.ToString(StringBuilder sb) { sb.Append(m_Item1); sb.Append(", "); sb.Append(m_Item2); sb.Append(", "); sb.Append(m_Item3); sb.Append(", "); sb.Append(m_Item4); sb.Append(", "); sb.Append(m_Item5); sb.Append(", "); sb.Append(m_Item6); sb.Append(")"); return sb.ToString(); } /// /// The number of positions in this data structure. /// int ITuple.Length => 6; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; case 4: return Item5; case 5: return Item6; default: throw new IndexOutOfRangeException(); } } } } [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { private readonly T1 m_Item1; private readonly T2 m_Item2; private readonly T3 m_Item3; private readonly T4 m_Item4; private readonly T5 m_Item5; private readonly T6 m_Item6; private readonly T7 m_Item7; public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } public T3 Item3 { get { return m_Item3; } } public T4 Item4 { get { return m_Item4; } } public T5 Item5 { get { return m_Item5; } } public T6 Item6 { get { return m_Item6; } } public T7 Item7 { get { return m_Item7; } } public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { m_Item1 = item1; m_Item2 = item2; m_Item3 = item3; m_Item4 = item4; m_Item5 = item5; m_Item6 = item6; m_Item7 = item7; } public override Boolean Equals(Object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); ; } Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { if (other == null) return false; Tuple objTuple = other as Tuple; if (objTuple == null) { return false; } return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4) && comparer.Equals(m_Item5, objTuple.m_Item5) && comparer.Equals(m_Item6, objTuple.m_Item6) && comparer.Equals(m_Item7, objTuple.m_Item7); } Int32 IComparable.CompareTo(Object obj) { return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); } Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { if (other == null) return 1; Tuple objTuple = other as Tuple; if (objTuple == null) { throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other"); } int c = 0; c = comparer.Compare(m_Item1, objTuple.m_Item1); if (c != 0) return c; c = comparer.Compare(m_Item2, objTuple.m_Item2); if (c != 0) return c; c = comparer.Compare(m_Item3, objTuple.m_Item3); if (c != 0) return c; c = comparer.Compare(m_Item4, objTuple.m_Item4); if (c != 0) return c; c = comparer.Compare(m_Item5, objTuple.m_Item5); if (c != 0) return c; c = comparer.Compare(m_Item6, objTuple.m_Item6); if (c != 0) return c; return comparer.Compare(m_Item7, objTuple.m_Item7); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7)); } Int32 ITupleInternal.GetHashCode(IEqualityComparer comparer) { return ((IStructuralEquatable)this).GetHashCode(comparer); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); return ((ITupleInternal)this).ToString(sb); } string ITupleInternal.ToString(StringBuilder sb) { sb.Append(m_Item1); sb.Append(", "); sb.Append(m_Item2); sb.Append(", "); sb.Append(m_Item3); sb.Append(", "); sb.Append(m_Item4); sb.Append(", "); sb.Append(m_Item5); sb.Append(", "); sb.Append(m_Item6); sb.Append(", "); sb.Append(m_Item7); sb.Append(")"); return sb.ToString(); } /// /// The number of positions in this data structure. /// int ITuple.Length => 7; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; case 4: return Item5; case 5: return Item6; case 6: return Item7; default: throw new IndexOutOfRangeException(); } } } } [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple { private readonly T1 m_Item1; private readonly T2 m_Item2; private readonly T3 m_Item3; private readonly T4 m_Item4; private readonly T5 m_Item5; private readonly T6 m_Item6; private readonly T7 m_Item7; private readonly TRest m_Rest; public T1 Item1 { get { return m_Item1; } } public T2 Item2 { get { return m_Item2; } } public T3 Item3 { get { return m_Item3; } } public T4 Item4 { get { return m_Item4; } } public T5 Item5 { get { return m_Item5; } } public T6 Item6 { get { return m_Item6; } } public T7 Item7 { get { return m_Item7; } } public TRest Rest { get { return m_Rest; } } public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { if (!(rest is ITupleInternal)) { throw new ArgumentException(SR.ArgumentException_TupleLastArgumentNotATuple); } m_Item1 = item1; m_Item2 = item2; m_Item3 = item3; m_Item4 = item4; m_Item5 = item5; m_Item6 = item6; m_Item7 = item7; m_Rest = rest; } public override Boolean Equals(Object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); ; } Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { if (other == null) return false; Tuple objTuple = other as Tuple; if (objTuple == null) { return false; } return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4) && comparer.Equals(m_Item5, objTuple.m_Item5) && comparer.Equals(m_Item6, objTuple.m_Item6) && comparer.Equals(m_Item7, objTuple.m_Item7) && comparer.Equals(m_Rest, objTuple.m_Rest); } Int32 IComparable.CompareTo(Object obj) { return ((IStructuralComparable)this).CompareTo(obj, Comparer.Default); } Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { if (other == null) return 1; Tuple objTuple = other as Tuple; if (objTuple == null) { throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other"); } int c = 0; c = comparer.Compare(m_Item1, objTuple.m_Item1); if (c != 0) return c; c = comparer.Compare(m_Item2, objTuple.m_Item2); if (c != 0) return c; c = comparer.Compare(m_Item3, objTuple.m_Item3); if (c != 0) return c; c = comparer.Compare(m_Item4, objTuple.m_Item4); if (c != 0) return c; c = comparer.Compare(m_Item5, objTuple.m_Item5); if (c != 0) return c; c = comparer.Compare(m_Item6, objTuple.m_Item6); if (c != 0) return c; c = comparer.Compare(m_Item7, objTuple.m_Item7); if (c != 0) return c; return comparer.Compare(m_Rest, objTuple.m_Rest); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple ITupleInternal t = (ITupleInternal)m_Rest; if (t.Length >= 8) { return t.GetHashCode(comparer); } // In this case, the rest memeber has less than 8 elements so we need to combine some our elements with the elements in rest int k = 8 - t.Length; switch (k) { case 1: return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); case 2: return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); case 3: return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); case 4: return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); case 5: return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); case 6: return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); case 7: return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); } Debug.Assert(false, "Missed all cases for computing Tuple hash code"); return -1; } Int32 ITupleInternal.GetHashCode(IEqualityComparer comparer) { return ((IStructuralEquatable)this).GetHashCode(comparer); } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); return ((ITupleInternal)this).ToString(sb); } string ITupleInternal.ToString(StringBuilder sb) { sb.Append(m_Item1); sb.Append(", "); sb.Append(m_Item2); sb.Append(", "); sb.Append(m_Item3); sb.Append(", "); sb.Append(m_Item4); sb.Append(", "); sb.Append(m_Item5); sb.Append(", "); sb.Append(m_Item6); sb.Append(", "); sb.Append(m_Item7); sb.Append(", "); return ((ITupleInternal)m_Rest).ToString(sb); } /// /// The number of positions in this data structure. /// int ITuple.Length { get { return 7 + ((ITupleInternal)Rest).Length; } } /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; case 4: return Item5; case 5: return Item6; case 6: return Item7; } return ((ITupleInternal)Rest)[index - 7]; } } } }