// 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.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using HashHelpers = System.Numerics.Hashing.HashHelpers;
namespace System
{
///
/// Helper so we can call some tuple methods recursively without knowing the underlying types.
///
internal interface IValueTupleInternal : ITuple
{
int GetHashCode(IEqualityComparer comparer);
string ToStringEnd();
}
///
/// The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies tuples in C# and struct tuples in F#.
/// Aside from created via language syntax, they are most easily created via the ValueTuple.Create factory methods.
/// The System.ValueTuple types differ from the System.Tuple types in that:
/// - they are structs rather than classes,
/// - they are mutable rather than readonly, and
/// - their members (such as Item1, Item2, etc) are fields rather than properties.
///
[Serializable]
public struct ValueTuple
: IEquatable, IStructuralEquatable, IStructuralComparable, IComparable, IComparable, IValueTupleInternal, ITuple
{
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if is a .
public override bool Equals(object obj)
{
return obj is ValueTuple;
}
/// Returns a value indicating whether this instance is equal to a specified value.
/// An instance to compare to this instance.
/// true if has the same value as this instance; otherwise, false.
public bool Equals(ValueTuple other)
{
return true;
}
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
return other is ValueTuple;
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return 0;
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
return 0;
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return 0;
}
/// Returns the hash code for this instance.
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return 0;
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return 0;
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return 0;
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form ().
///
public override string ToString()
{
return "()";
}
string IValueTupleInternal.ToStringEnd()
{
return ")";
}
///
/// The number of positions in this data structure.
///
int ITuple.Length => 0;
///
/// Get the element at position .
///
object ITuple.this[int index]
{
get
{
throw new IndexOutOfRangeException();
}
}
/// Creates a new struct 0-tuple.
/// A 0-tuple.
public static ValueTuple Create() =>
new ValueTuple();
/// Creates a new struct 1-tuple, or singleton.
/// The type of the first component of the tuple.
/// The value of the first component of the tuple.
/// A 1-tuple (singleton) whose value is (item1).
public static ValueTuple Create(T1 item1) =>
new ValueTuple(item1);
/// Creates a new struct 2-tuple, or pair.
/// The type of the first component of the tuple.
/// The type of the second component of the tuple.
/// The value of the first component of the tuple.
/// The value of the second component of the tuple.
/// A 2-tuple (pair) whose value is (item1, item2).
public static ValueTuple Create(T1 item1, T2 item2) =>
new ValueTuple(item1, item2);
/// Creates a new struct 3-tuple, or triple.
/// The type of the first component of the tuple.
/// The type of the second component of the tuple.
/// The type of the third component of the tuple.
/// The value of the first component of the tuple.
/// The value of the second component of the tuple.
/// The value of the third component of the tuple.
/// A 3-tuple (triple) whose value is (item1, item2, item3).
public static ValueTuple Create(T1 item1, T2 item2, T3 item3) =>
new ValueTuple(item1, item2, item3);
/// Creates a new struct 4-tuple, or quadruple.
/// The type of the first component of the tuple.
/// The type of the second component of the tuple.
/// The type of the third component of the tuple.
/// The type of the fourth component of the tuple.
/// The value of the first component of the tuple.
/// The value of the second component of the tuple.
/// The value of the third component of the tuple.
/// The value of the fourth component of the tuple.
/// A 4-tuple (quadruple) whose value is (item1, item2, item3, item4).
public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) =>
new ValueTuple(item1, item2, item3, item4);
/// Creates a new struct 5-tuple, or quintuple.
/// The type of the first component of the tuple.
/// The type of the second component of the tuple.
/// The type of the third component of the tuple.
/// The type of the fourth component of the tuple.
/// The type of the fifth component of the tuple.
/// The value of the first component of the tuple.
/// The value of the second component of the tuple.
/// The value of the third component of the tuple.
/// The value of the fourth component of the tuple.
/// The value of the fifth component of the tuple.
/// A 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5).
public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) =>
new ValueTuple(item1, item2, item3, item4, item5);
/// Creates a new struct 6-tuple, or sextuple.
/// The type of the first component of the tuple.
/// The type of the second component of the tuple.
/// The type of the third component of the tuple.
/// The type of the fourth component of the tuple.
/// The type of the fifth component of the tuple.
/// The type of the sixth component of the tuple.
/// The value of the first component of the tuple.
/// The value of the second component of the tuple.
/// The value of the third component of the tuple.
/// The value of the fourth component of the tuple.
/// The value of the fifth component of the tuple.
/// The value of the sixth component of the tuple.
/// A 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6).
public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) =>
new ValueTuple(item1, item2, item3, item4, item5, item6);
/// Creates a new struct 7-tuple, or septuple.
/// The type of the first component of the tuple.
/// The type of the second component of the tuple.
/// The type of the third component of the tuple.
/// The type of the fourth component of the tuple.
/// The type of the fifth component of the tuple.
/// The type of the sixth component of the tuple.
/// The type of the seventh component of the tuple.
/// The value of the first component of the tuple.
/// The value of the second component of the tuple.
/// The value of the third component of the tuple.
/// The value of the fourth component of the tuple.
/// The value of the fifth component of the tuple.
/// The value of the sixth component of the tuple.
/// The value of the seventh component of the tuple.
/// A 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7).
public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) =>
new ValueTuple(item1, item2, item3, item4, item5, item6, item7);
/// Creates a new struct 8-tuple, or octuple.
/// The type of the first component of the tuple.
/// The type of the second component of the tuple.
/// The type of the third component of the tuple.
/// The type of the fourth component of the tuple.
/// The type of the fifth component of the tuple.
/// The type of the sixth component of the tuple.
/// The type of the seventh component of the tuple.
/// The type of the eighth component of the tuple.
/// The value of the first component of the tuple.
/// The value of the second component of the tuple.
/// The value of the third component of the tuple.
/// The value of the fourth component of the tuple.
/// The value of the fifth component of the tuple.
/// The value of the sixth component of the tuple.
/// The value of the seventh component of the tuple.
/// The value of the eighth component of the tuple.
/// An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8).
public static ValueTuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) =>
new ValueTuple>(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create(item8));
internal static int CombineHashCodes(int h1, int h2)
{
return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2);
}
internal static int CombineHashCodes(int h1, int h2, int h3)
{
return HashHelpers.Combine(CombineHashCodes(h1, h2), h3);
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4)
{
return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4);
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5)
{
return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5);
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6)
{
return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6);
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7)
{
return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7);
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8)
{
return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8);
}
}
/// Represents a 1-tuple, or singleton, as a value type.
/// The type of the tuple's only component.
[Serializable]
public struct ValueTuple
: IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple
{
///
/// The current instance's first component.
///
public T1 Item1;
///
/// Initializes a new instance of the value type.
///
/// The value of the tuple's first component.
public ValueTuple(T1 item1)
{
Item1 = item1;
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if the current instance is equal to the specified object; otherwise, .
///
/// The parameter is considered to be equal to the current instance under the following conditions:
///
/// - It is a value type.
/// - Its components are of the same types as those of the current instance.
/// - Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
///
///
public override bool Equals(object obj)
{
return obj is ValueTuple && Equals((ValueTuple)obj);
}
///
/// Returns a value that indicates whether the current
/// instance is equal to a specified .
///
/// The tuple to compare with this instance.
/// if the current instance is equal to the specified tuple; otherwise, .
///
/// The parameter is considered to be equal to the current instance if each of its field
/// is equal to that of the current instance, using the default comparer for that field's type.
///
public bool Equals(ValueTuple other)
{
return EqualityComparer.Default.Equals(Item1, other.Item1);
}
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null || !(other is ValueTuple)) return false;
var objTuple = (ValueTuple)other;
return comparer.Equals(Item1, objTuple.Item1);
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
return Comparer.Default.Compare(Item1, objTuple.Item1);
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
return Comparer.Default.Compare(Item1, other.Item1);
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
return comparer.Compare(Item1, objTuple.Item1);
}
///
/// Returns the hash code for the current instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return Item1?.GetHashCode() ?? 0;
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return comparer.GetHashCode(Item1);
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return comparer.GetHashCode(Item1);
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form (Item1),
/// where Item1 represents the value of . If the field is ,
/// it is represented as .
///
public override string ToString()
{
return "(" + Item1?.ToString() + ")";
}
string IValueTupleInternal.ToStringEnd()
{
return Item1?.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;
}
}
}
///
/// Represents a 2-tuple, or pair, as a value type.
///
/// The type of the tuple's first component.
/// The type of the tuple's second component.
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple
: IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple
{
///
/// The current instance's first component.
///
public T1 Item1;
///
/// The current instance's first component.
///
public T2 Item2;
///
/// Initializes a new instance of the value type.
///
/// The value of the tuple's first component.
/// The value of the tuple's second component.
public ValueTuple(T1 item1, T2 item2)
{
Item1 = item1;
Item2 = item2;
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if the current instance is equal to the specified object; otherwise, .
///
///
/// The parameter is considered to be equal to the current instance under the following conditions:
///
/// - It is a value type.
/// - Its components are of the same types as those of the current instance.
/// - Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
///
///
public override bool Equals(object obj)
{
return obj is ValueTuple && Equals((ValueTuple)obj);
}
///
/// Returns a value that indicates whether the current instance is equal to a specified .
///
/// The tuple to compare with this instance.
/// if the current instance is equal to the specified tuple; otherwise, .
///
/// The parameter is considered to be equal to the current instance if each of its fields
/// are equal to that of the current instance, using the default comparer for that field's type.
///
public bool Equals(ValueTuple other)
{
return EqualityComparer.Default.Equals(Item1, other.Item1)
&& EqualityComparer.Default.Equals(Item2, other.Item2);
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object based on a specified comparison method.
///
/// The object to compare with this instance.
/// An object that defines the method to use to evaluate whether the two objects are equal.
/// if the current instance is equal to the specified object; otherwise, .
///
///
/// This member is an explicit interface member implementation. It can be used only when the
/// instance is cast to an interface.
///
/// The implementation is called only if other is not ,
/// and if it can be successfully cast (in C#) or converted (in Visual Basic) to a
/// whose components are of the same types as those of the current instance. The IStructuralEquatable.Equals(Object, IEqualityComparer) method
/// first passes the values of the objects to be compared to the
/// implementation. If this method call returns , the method is
/// called again and passed the values of the two instances.
///
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null || !(other is ValueTuple)) return false;
var objTuple = (ValueTuple)other;
return comparer.Equals(Item1, objTuple.Item1)
&& comparer.Equals(Item2, objTuple.Item2);
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return CompareTo((ValueTuple)other);
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
int c = Comparer.Default.Compare(Item1, other.Item1);
if (c != 0) return c;
return Comparer.Default.Compare(Item2, other.Item2);
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
int c = comparer.Compare(Item1, objTuple.Item1);
if (c != 0) return c;
return comparer.Compare(Item2, objTuple.Item2);
}
///
/// Returns the hash code for the current instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
Item2?.GetHashCode() ?? 0);
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
private int GetHashCodeCore(IEqualityComparer comparer)
{
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
comparer.GetHashCode(Item2));
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form (Item1, Item2),
/// where Item1 and Item2 represent the values of the
/// and fields. If either field value is ,
/// it is represented as .
///
public override string ToString()
{
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")";
}
string IValueTupleInternal.ToStringEnd()
{
return Item1?.ToString() + ", " + Item2?.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();
}
}
}
}
///
/// Represents a 3-tuple, or triple, as a value type.
///
/// The type of the tuple's first component.
/// The type of the tuple's second component.
/// The type of the tuple's third component.
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple
: IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple
{
///
/// The current instance's first component.
///
public T1 Item1;
///
/// The current instance's second component.
///
public T2 Item2;
///
/// The current instance's third component.
///
public T3 Item3;
///
/// Initializes a new instance of the value type.
///
/// The value of the tuple's first component.
/// The value of the tuple's second component.
/// The value of the tuple's third component.
public ValueTuple(T1 item1, T2 item2, T3 item3)
{
Item1 = item1;
Item2 = item2;
Item3 = item3;
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if the current instance is equal to the specified object; otherwise, .
///
/// The parameter is considered to be equal to the current instance under the following conditions:
///
/// - It is a value type.
/// - Its components are of the same types as those of the current instance.
/// - Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
///
///
public override bool Equals(object obj)
{
return obj is ValueTuple && Equals((ValueTuple)obj);
}
///
/// Returns a value that indicates whether the current
/// instance is equal to a specified .
///
/// The tuple to compare with this instance.
/// if the current instance is equal to the specified tuple; otherwise, .
///
/// The parameter is considered to be equal to the current instance if each of its fields
/// are equal to that of the current instance, using the default comparer for that field's type.
///
public bool Equals(ValueTuple other)
{
return EqualityComparer.Default.Equals(Item1, other.Item1)
&& EqualityComparer.Default.Equals(Item2, other.Item2)
&& EqualityComparer.Default.Equals(Item3, other.Item3);
}
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null || !(other is ValueTuple)) return false;
var objTuple = (ValueTuple)other;
return comparer.Equals(Item1, objTuple.Item1)
&& comparer.Equals(Item2, objTuple.Item2)
&& comparer.Equals(Item3, objTuple.Item3);
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return CompareTo((ValueTuple)other);
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
int c = Comparer.Default.Compare(Item1, other.Item1);
if (c != 0) return c;
c = Comparer.Default.Compare(Item2, other.Item2);
if (c != 0) return c;
return Comparer.Default.Compare(Item3, other.Item3);
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
int c = comparer.Compare(Item1, objTuple.Item1);
if (c != 0) return c;
c = comparer.Compare(Item2, objTuple.Item2);
if (c != 0) return c;
return comparer.Compare(Item3, objTuple.Item3);
}
///
/// Returns the hash code for the current instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
Item2?.GetHashCode() ?? 0,
Item3?.GetHashCode() ?? 0);
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
private int GetHashCodeCore(IEqualityComparer comparer)
{
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
comparer.GetHashCode(Item2),
comparer.GetHashCode(Item3));
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form (Item1, Item2, Item3).
/// If any field value is , it is represented as .
///
public override string ToString()
{
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
}
string IValueTupleInternal.ToStringEnd()
{
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.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();
}
}
}
}
///
/// Represents a 4-tuple, or quadruple, as a value type.
///
/// The type of the tuple's first component.
/// The type of the tuple's second component.
/// The type of the tuple's third component.
/// The type of the tuple's fourth component.
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple
: IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple
{
///
/// The current instance's first component.
///
public T1 Item1;
///
/// The current instance's second component.
///
public T2 Item2;
///
/// The current instance's third component.
///
public T3 Item3;
///
/// The current instance's fourth component.
///
public T4 Item4;
///
/// Initializes a new instance of the value type.
///
/// The value of the tuple's first component.
/// The value of the tuple's second component.
/// The value of the tuple's third component.
/// The value of the tuple's fourth component.
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4)
{
Item1 = item1;
Item2 = item2;
Item3 = item3;
Item4 = item4;
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if the current instance is equal to the specified object; otherwise, .
///
/// The parameter is considered to be equal to the current instance under the following conditions:
///
/// - It is a value type.
/// - Its components are of the same types as those of the current instance.
/// - Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
///
///
public override bool Equals(object obj)
{
return obj is ValueTuple && Equals((ValueTuple)obj);
}
///
/// Returns a value that indicates whether the current
/// instance is equal to a specified .
///
/// The tuple to compare with this instance.
/// if the current instance is equal to the specified tuple; otherwise, .
///
/// The parameter is considered to be equal to the current instance if each of its fields
/// are equal to that of the current instance, using the default comparer for that field's type.
///
public bool Equals(ValueTuple other)
{
return EqualityComparer.Default.Equals(Item1, other.Item1)
&& EqualityComparer.Default.Equals(Item2, other.Item2)
&& EqualityComparer.Default.Equals(Item3, other.Item3)
&& EqualityComparer.Default.Equals(Item4, other.Item4);
}
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null || !(other is ValueTuple)) return false;
var objTuple = (ValueTuple)other;
return comparer.Equals(Item1, objTuple.Item1)
&& comparer.Equals(Item2, objTuple.Item2)
&& comparer.Equals(Item3, objTuple.Item3)
&& comparer.Equals(Item4, objTuple.Item4);
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return CompareTo((ValueTuple)other);
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
int c = Comparer.Default.Compare(Item1, other.Item1);
if (c != 0) return c;
c = Comparer.Default.Compare(Item2, other.Item2);
if (c != 0) return c;
c = Comparer.Default.Compare(Item3, other.Item3);
if (c != 0) return c;
return Comparer.Default.Compare(Item4, other.Item4);
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
int c = comparer.Compare(Item1, objTuple.Item1);
if (c != 0) return c;
c = comparer.Compare(Item2, objTuple.Item2);
if (c != 0) return c;
c = comparer.Compare(Item3, objTuple.Item3);
if (c != 0) return c;
return comparer.Compare(Item4, objTuple.Item4);
}
///
/// Returns the hash code for the current instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
Item2?.GetHashCode() ?? 0,
Item3?.GetHashCode() ?? 0,
Item4?.GetHashCode() ?? 0);
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
private int GetHashCodeCore(IEqualityComparer comparer)
{
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
comparer.GetHashCode(Item2),
comparer.GetHashCode(Item3),
comparer.GetHashCode(Item4));
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form (Item1, Item2, Item3, Item4).
/// If any field value is , it is represented as .
///
public override string ToString()
{
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
}
string IValueTupleInternal.ToStringEnd()
{
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.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();
}
}
}
}
///
/// Represents a 5-tuple, or quintuple, as a value type.
///
/// The type of the tuple's first component.
/// The type of the tuple's second component.
/// The type of the tuple's third component.
/// The type of the tuple's fourth component.
/// The type of the tuple's fifth component.
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple
: IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple
{
///
/// The current instance's first component.
///
public T1 Item1;
///
/// The current instance's second component.
///
public T2 Item2;
///
/// The current instance's third component.
///
public T3 Item3;
///
/// The current instance's fourth component.
///
public T4 Item4;
///
/// The current instance's fifth component.
///
public T5 Item5;
///
/// Initializes a new instance of the value type.
///
/// The value of the tuple's first component.
/// The value of the tuple's second component.
/// The value of the tuple's third component.
/// The value of the tuple's fourth component.
/// The value of the tuple's fifth component.
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
{
Item1 = item1;
Item2 = item2;
Item3 = item3;
Item4 = item4;
Item5 = item5;
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if the current instance is equal to the specified object; otherwise, .
///
/// The parameter is considered to be equal to the current instance under the following conditions:
///
/// - It is a value type.
/// - Its components are of the same types as those of the current instance.
/// - Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
///
///
public override bool Equals(object obj)
{
return obj is ValueTuple && Equals((ValueTuple)obj);
}
///
/// Returns a value that indicates whether the current
/// instance is equal to a specified .
///
/// The tuple to compare with this instance.
/// if the current instance is equal to the specified tuple; otherwise, .
///
/// The parameter is considered to be equal to the current instance if each of its fields
/// are equal to that of the current instance, using the default comparer for that field's type.
///
public bool Equals(ValueTuple other)
{
return EqualityComparer.Default.Equals(Item1, other.Item1)
&& EqualityComparer.Default.Equals(Item2, other.Item2)
&& EqualityComparer.Default.Equals(Item3, other.Item3)
&& EqualityComparer.Default.Equals(Item4, other.Item4)
&& EqualityComparer.Default.Equals(Item5, other.Item5);
}
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null || !(other is ValueTuple)) return false;
var objTuple = (ValueTuple)other;
return comparer.Equals(Item1, objTuple.Item1)
&& comparer.Equals(Item2, objTuple.Item2)
&& comparer.Equals(Item3, objTuple.Item3)
&& comparer.Equals(Item4, objTuple.Item4)
&& comparer.Equals(Item5, objTuple.Item5);
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return CompareTo((ValueTuple)other);
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
int c = Comparer.Default.Compare(Item1, other.Item1);
if (c != 0) return c;
c = Comparer.Default.Compare(Item2, other.Item2);
if (c != 0) return c;
c = Comparer.Default.Compare(Item3, other.Item3);
if (c != 0) return c;
c = Comparer.Default.Compare(Item4, other.Item4);
if (c != 0) return c;
return Comparer.Default.Compare(Item5, other.Item5);
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
int c = comparer.Compare(Item1, objTuple.Item1);
if (c != 0) return c;
c = comparer.Compare(Item2, objTuple.Item2);
if (c != 0) return c;
c = comparer.Compare(Item3, objTuple.Item3);
if (c != 0) return c;
c = comparer.Compare(Item4, objTuple.Item4);
if (c != 0) return c;
return comparer.Compare(Item5, objTuple.Item5);
}
///
/// Returns the hash code for the current instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
Item2?.GetHashCode() ?? 0,
Item3?.GetHashCode() ?? 0,
Item4?.GetHashCode() ?? 0,
Item5?.GetHashCode() ?? 0);
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
private int GetHashCodeCore(IEqualityComparer comparer)
{
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
comparer.GetHashCode(Item2),
comparer.GetHashCode(Item3),
comparer.GetHashCode(Item4),
comparer.GetHashCode(Item5));
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5).
/// If any field value is , it is represented as .
///
public override string ToString()
{
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
}
string IValueTupleInternal.ToStringEnd()
{
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.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();
}
}
}
}
///
/// Represents a 6-tuple, or sixtuple, as a value type.
///
/// The type of the tuple's first component.
/// The type of the tuple's second component.
/// The type of the tuple's third component.
/// The type of the tuple's fourth component.
/// The type of the tuple's fifth component.
/// The type of the tuple's sixth component.
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple
: IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple
{
///
/// The current instance's first component.
///
public T1 Item1;
///
/// The current instance's second component.
///
public T2 Item2;
///
/// The current instance's third component.
///
public T3 Item3;
///
/// The current instance's fourth component.
///
public T4 Item4;
///
/// The current instance's fifth component.
///
public T5 Item5;
///
/// The current instance's sixth component.
///
public T6 Item6;
///
/// Initializes a new instance of the value type.
///
/// The value of the tuple's first component.
/// The value of the tuple's second component.
/// The value of the tuple's third component.
/// The value of the tuple's fourth component.
/// The value of the tuple's fifth component.
/// The value of the tuple's sixth component.
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
{
Item1 = item1;
Item2 = item2;
Item3 = item3;
Item4 = item4;
Item5 = item5;
Item6 = item6;
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if the current instance is equal to the specified object; otherwise, .
///
/// The parameter is considered to be equal to the current instance under the following conditions:
///
/// - It is a value type.
/// - Its components are of the same types as those of the current instance.
/// - Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
///
///
public override bool Equals(object obj)
{
return obj is ValueTuple && Equals((ValueTuple)obj);
}
///
/// Returns a value that indicates whether the current
/// instance is equal to a specified .
///
/// The tuple to compare with this instance.
/// if the current instance is equal to the specified tuple; otherwise, .
///
/// The parameter is considered to be equal to the current instance if each of its fields
/// are equal to that of the current instance, using the default comparer for that field's type.
///
public bool Equals(ValueTuple other)
{
return EqualityComparer.Default.Equals(Item1, other.Item1)
&& EqualityComparer.Default.Equals(Item2, other.Item2)
&& EqualityComparer.Default.Equals(Item3, other.Item3)
&& EqualityComparer.Default.Equals(Item4, other.Item4)
&& EqualityComparer.Default.Equals(Item5, other.Item5)
&& EqualityComparer.Default.Equals(Item6, other.Item6);
}
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null || !(other is ValueTuple)) return false;
var objTuple = (ValueTuple)other;
return comparer.Equals(Item1, objTuple.Item1)
&& comparer.Equals(Item2, objTuple.Item2)
&& comparer.Equals(Item3, objTuple.Item3)
&& comparer.Equals(Item4, objTuple.Item4)
&& comparer.Equals(Item5, objTuple.Item5)
&& comparer.Equals(Item6, objTuple.Item6);
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return CompareTo((ValueTuple)other);
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
int c = Comparer.Default.Compare(Item1, other.Item1);
if (c != 0) return c;
c = Comparer.Default.Compare(Item2, other.Item2);
if (c != 0) return c;
c = Comparer.Default.Compare(Item3, other.Item3);
if (c != 0) return c;
c = Comparer.Default.Compare(Item4, other.Item4);
if (c != 0) return c;
c = Comparer.Default.Compare(Item5, other.Item5);
if (c != 0) return c;
return Comparer.Default.Compare(Item6, other.Item6);
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
int c = comparer.Compare(Item1, objTuple.Item1);
if (c != 0) return c;
c = comparer.Compare(Item2, objTuple.Item2);
if (c != 0) return c;
c = comparer.Compare(Item3, objTuple.Item3);
if (c != 0) return c;
c = comparer.Compare(Item4, objTuple.Item4);
if (c != 0) return c;
c = comparer.Compare(Item5, objTuple.Item5);
if (c != 0) return c;
return comparer.Compare(Item6, objTuple.Item6);
}
///
/// Returns the hash code for the current instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
Item2?.GetHashCode() ?? 0,
Item3?.GetHashCode() ?? 0,
Item4?.GetHashCode() ?? 0,
Item5?.GetHashCode() ?? 0,
Item6?.GetHashCode() ?? 0);
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
private int GetHashCodeCore(IEqualityComparer comparer)
{
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
comparer.GetHashCode(Item2),
comparer.GetHashCode(Item3),
comparer.GetHashCode(Item4),
comparer.GetHashCode(Item5),
comparer.GetHashCode(Item6));
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6).
/// If any field value is , it is represented as .
///
public override string ToString()
{
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
}
string IValueTupleInternal.ToStringEnd()
{
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.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();
}
}
}
}
///
/// Represents a 7-tuple, or sentuple, as a value type.
///
/// The type of the tuple's first component.
/// The type of the tuple's second component.
/// The type of the tuple's third component.
/// The type of the tuple's fourth component.
/// The type of the tuple's fifth component.
/// The type of the tuple's sixth component.
/// The type of the tuple's seventh component.
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple
: IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple
{
///
/// The current instance's first component.
///
public T1 Item1;
///
/// The current instance's second component.
///
public T2 Item2;
///
/// The current instance's third component.
///
public T3 Item3;
///
/// The current instance's fourth component.
///
public T4 Item4;
///
/// The current instance's fifth component.
///
public T5 Item5;
///
/// The current instance's sixth component.
///
public T6 Item6;
///
/// The current instance's seventh component.
///
public T7 Item7;
///
/// Initializes a new instance of the value type.
///
/// The value of the tuple's first component.
/// The value of the tuple's second component.
/// The value of the tuple's third component.
/// The value of the tuple's fourth component.
/// The value of the tuple's fifth component.
/// The value of the tuple's sixth component.
/// The value of the tuple's seventh component.
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
{
Item1 = item1;
Item2 = item2;
Item3 = item3;
Item4 = item4;
Item5 = item5;
Item6 = item6;
Item7 = item7;
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if the current instance is equal to the specified object; otherwise, .
///
/// The parameter is considered to be equal to the current instance under the following conditions:
///
/// - It is a value type.
/// - Its components are of the same types as those of the current instance.
/// - Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
///
///
public override bool Equals(object obj)
{
return obj is ValueTuple && Equals((ValueTuple)obj);
}
///
/// Returns a value that indicates whether the current
/// instance is equal to a specified .
///
/// The tuple to compare with this instance.
/// if the current instance is equal to the specified tuple; otherwise, .
///
/// The parameter is considered to be equal to the current instance if each of its fields
/// are equal to that of the current instance, using the default comparer for that field's type.
///
public bool Equals(ValueTuple other)
{
return EqualityComparer.Default.Equals(Item1, other.Item1)
&& EqualityComparer.Default.Equals(Item2, other.Item2)
&& EqualityComparer.Default.Equals(Item3, other.Item3)
&& EqualityComparer.Default.Equals(Item4, other.Item4)
&& EqualityComparer.Default.Equals(Item5, other.Item5)
&& EqualityComparer.Default.Equals(Item6, other.Item6)
&& EqualityComparer.Default.Equals(Item7, other.Item7);
}
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null || !(other is ValueTuple)) return false;
var objTuple = (ValueTuple)other;
return comparer.Equals(Item1, objTuple.Item1)
&& comparer.Equals(Item2, objTuple.Item2)
&& comparer.Equals(Item3, objTuple.Item3)
&& comparer.Equals(Item4, objTuple.Item4)
&& comparer.Equals(Item5, objTuple.Item5)
&& comparer.Equals(Item6, objTuple.Item6)
&& comparer.Equals(Item7, objTuple.Item7);
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return CompareTo((ValueTuple)other);
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
int c = Comparer.Default.Compare(Item1, other.Item1);
if (c != 0) return c;
c = Comparer.Default.Compare(Item2, other.Item2);
if (c != 0) return c;
c = Comparer.Default.Compare(Item3, other.Item3);
if (c != 0) return c;
c = Comparer.Default.Compare(Item4, other.Item4);
if (c != 0) return c;
c = Comparer.Default.Compare(Item5, other.Item5);
if (c != 0) return c;
c = Comparer.Default.Compare(Item6, other.Item6);
if (c != 0) return c;
return Comparer.Default.Compare(Item7, other.Item7);
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
int c = comparer.Compare(Item1, objTuple.Item1);
if (c != 0) return c;
c = comparer.Compare(Item2, objTuple.Item2);
if (c != 0) return c;
c = comparer.Compare(Item3, objTuple.Item3);
if (c != 0) return c;
c = comparer.Compare(Item4, objTuple.Item4);
if (c != 0) return c;
c = comparer.Compare(Item5, objTuple.Item5);
if (c != 0) return c;
c = comparer.Compare(Item6, objTuple.Item6);
if (c != 0) return c;
return comparer.Compare(Item7, objTuple.Item7);
}
///
/// Returns the hash code for the current instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
Item2?.GetHashCode() ?? 0,
Item3?.GetHashCode() ?? 0,
Item4?.GetHashCode() ?? 0,
Item5?.GetHashCode() ?? 0,
Item6?.GetHashCode() ?? 0,
Item7?.GetHashCode() ?? 0);
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
private int GetHashCodeCore(IEqualityComparer comparer)
{
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
comparer.GetHashCode(Item2),
comparer.GetHashCode(Item3),
comparer.GetHashCode(Item4),
comparer.GetHashCode(Item5),
comparer.GetHashCode(Item6),
comparer.GetHashCode(Item7));
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7).
/// If any field value is , it is represented as .
///
public override string ToString()
{
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
}
string IValueTupleInternal.ToStringEnd()
{
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.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();
}
}
}
}
///
/// Represents an 8-tuple, or octuple, as a value type.
///
/// The type of the tuple's first component.
/// The type of the tuple's second component.
/// The type of the tuple's third component.
/// The type of the tuple's fourth component.
/// The type of the tuple's fifth component.
/// The type of the tuple's sixth component.
/// The type of the tuple's seventh component.
/// The type of the tuple's eighth component.
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple
: IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple
where TRest : struct
{
///
/// The current instance's first component.
///
public T1 Item1;
///
/// The current instance's second component.
///
public T2 Item2;
///
/// The current instance's third component.
///
public T3 Item3;
///
/// The current instance's fourth component.
///
public T4 Item4;
///
/// The current instance's fifth component.
///
public T5 Item5;
///
/// The current instance's sixth component.
///
public T6 Item6;
///
/// The current instance's seventh component.
///
public T7 Item7;
///
/// The current instance's eighth component.
///
public TRest Rest;
///
/// Initializes a new instance of the value type.
///
/// The value of the tuple's first component.
/// The value of the tuple's second component.
/// The value of the tuple's third component.
/// The value of the tuple's fourth component.
/// The value of the tuple's fifth component.
/// The value of the tuple's sixth component.
/// The value of the tuple's seventh component.
/// The value of the tuple's eight component.
public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
{
if (!(rest is IValueTupleInternal))
{
throw new ArgumentException(SR.ArgumentException_ValueTupleLastArgumentNotAValueTuple);
}
Item1 = item1;
Item2 = item2;
Item3 = item3;
Item4 = item4;
Item5 = item5;
Item6 = item6;
Item7 = item7;
Rest = rest;
}
///
/// Returns a value that indicates whether the current instance is equal to a specified object.
///
/// The object to compare with this instance.
/// if the current instance is equal to the specified object; otherwise, .
///
/// The parameter is considered to be equal to the current instance under the following conditions:
///
/// - It is a value type.
/// - Its components are of the same types as those of the current instance.
/// - Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
///
///
public override bool Equals(object obj)
{
return obj is ValueTuple && Equals((ValueTuple)obj);
}
///
/// Returns a value that indicates whether the current
/// instance is equal to a specified .
///
/// The tuple to compare with this instance.
/// if the current instance is equal to the specified tuple; otherwise, .
///
/// The parameter is considered to be equal to the current instance if each of its fields
/// are equal to that of the current instance, using the default comparer for that field's type.
///
public bool Equals(ValueTuple other)
{
return EqualityComparer.Default.Equals(Item1, other.Item1)
&& EqualityComparer.Default.Equals(Item2, other.Item2)
&& EqualityComparer.Default.Equals(Item3, other.Item3)
&& EqualityComparer.Default.Equals(Item4, other.Item4)
&& EqualityComparer.Default.Equals(Item5, other.Item5)
&& EqualityComparer.Default.Equals(Item6, other.Item6)
&& EqualityComparer.Default.Equals(Item7, other.Item7)
&& EqualityComparer.Default.Equals(Rest, other.Rest);
}
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null || !(other is ValueTuple)) return false;
var objTuple = (ValueTuple)other;
return comparer.Equals(Item1, objTuple.Item1)
&& comparer.Equals(Item2, objTuple.Item2)
&& comparer.Equals(Item3, objTuple.Item3)
&& comparer.Equals(Item4, objTuple.Item4)
&& comparer.Equals(Item5, objTuple.Item5)
&& comparer.Equals(Item6, objTuple.Item6)
&& comparer.Equals(Item7, objTuple.Item7)
&& comparer.Equals(Rest, objTuple.Rest);
}
int IComparable.CompareTo(object other)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
return CompareTo((ValueTuple)other);
}
/// Compares this instance to a specified instance and returns an indication of their relative values.
/// An instance to compare.
///
/// A signed number indicating the relative values of this instance and .
/// Returns less than zero if this instance is less than , zero if this
/// instance is equal to , and greater than zero if this instance is greater
/// than .
///
public int CompareTo(ValueTuple other)
{
int c = Comparer.Default.Compare(Item1, other.Item1);
if (c != 0) return c;
c = Comparer.Default.Compare(Item2, other.Item2);
if (c != 0) return c;
c = Comparer.Default.Compare(Item3, other.Item3);
if (c != 0) return c;
c = Comparer.Default.Compare(Item4, other.Item4);
if (c != 0) return c;
c = Comparer.Default.Compare(Item5, other.Item5);
if (c != 0) return c;
c = Comparer.Default.Compare(Item6, other.Item6);
if (c != 0) return c;
c = Comparer.Default.Compare(Item7, other.Item7);
if (c != 0) return c;
return Comparer.Default.Compare(Rest, other.Rest);
}
int IStructuralComparable.CompareTo(object other, IComparer comparer)
{
if (other == null) return 1;
if (!(other is ValueTuple))
{
throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
}
var objTuple = (ValueTuple)other;
int c = comparer.Compare(Item1, objTuple.Item1);
if (c != 0) return c;
c = comparer.Compare(Item2, objTuple.Item2);
if (c != 0) return c;
c = comparer.Compare(Item3, objTuple.Item3);
if (c != 0) return c;
c = comparer.Compare(Item4, objTuple.Item4);
if (c != 0) return c;
c = comparer.Compare(Item5, objTuple.Item5);
if (c != 0) return c;
c = comparer.Compare(Item6, objTuple.Item6);
if (c != 0) return c;
c = comparer.Compare(Item7, objTuple.Item7);
if (c != 0) return c;
return comparer.Compare(Rest, objTuple.Rest);
}
///
/// Returns the hash code for the current instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
// We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
IValueTupleInternal rest = Rest as IValueTupleInternal;
if (rest == null)
{
return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
Item2?.GetHashCode() ?? 0,
Item3?.GetHashCode() ?? 0,
Item4?.GetHashCode() ?? 0,
Item5?.GetHashCode() ?? 0,
Item6?.GetHashCode() ?? 0,
Item7?.GetHashCode() ?? 0);
}
int size = rest.Length;
if (size >= 8) { return rest.GetHashCode(); }
// In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest
int k = 8 - size;
switch (k)
{
case 1:
return ValueTuple.CombineHashCodes(Item7?.GetHashCode() ?? 0,
rest.GetHashCode());
case 2:
return ValueTuple.CombineHashCodes(Item6?.GetHashCode() ?? 0,
Item7?.GetHashCode() ?? 0,
rest.GetHashCode());
case 3:
return ValueTuple.CombineHashCodes(Item5?.GetHashCode() ?? 0,
Item6?.GetHashCode() ?? 0,
Item7?.GetHashCode() ?? 0,
rest.GetHashCode());
case 4:
return ValueTuple.CombineHashCodes(Item4?.GetHashCode() ?? 0,
Item5?.GetHashCode() ?? 0,
Item6?.GetHashCode() ?? 0,
Item7?.GetHashCode() ?? 0,
rest.GetHashCode());
case 5:
return ValueTuple.CombineHashCodes(Item3?.GetHashCode() ?? 0,
Item4?.GetHashCode() ?? 0,
Item5?.GetHashCode() ?? 0,
Item6?.GetHashCode() ?? 0,
Item7?.GetHashCode() ?? 0,
rest.GetHashCode());
case 6:
return ValueTuple.CombineHashCodes(Item2?.GetHashCode() ?? 0,
Item3?.GetHashCode() ?? 0,
Item4?.GetHashCode() ?? 0,
Item5?.GetHashCode() ?? 0,
Item6?.GetHashCode() ?? 0,
Item7?.GetHashCode() ?? 0,
rest.GetHashCode());
case 7:
case 8:
return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
Item2?.GetHashCode() ?? 0,
Item3?.GetHashCode() ?? 0,
Item4?.GetHashCode() ?? 0,
Item5?.GetHashCode() ?? 0,
Item6?.GetHashCode() ?? 0,
Item7?.GetHashCode() ?? 0,
rest.GetHashCode());
}
Contract.Assert(false, "Missed all cases for computing ValueTuple hash code");
return -1;
}
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
private int GetHashCodeCore(IEqualityComparer comparer)
{
// We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
IValueTupleInternal rest = Rest as IValueTupleInternal;
if (rest == null)
{
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3),
comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
comparer.GetHashCode(Item7));
}
int size = rest.Length;
if (size >= 8) { return rest.GetHashCode(comparer); }
// In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest
int k = 8 - size;
switch (k)
{
case 1:
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
case 2:
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
case 3:
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7),
rest.GetHashCode(comparer));
case 4:
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
case 5:
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5),
comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
case 6:
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4),
comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7),
rest.GetHashCode(comparer));
case 7:
case 8:
return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3),
comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
}
Contract.Assert(false, "Missed all cases for computing ValueTuple hash code");
return -1;
}
int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
{
return GetHashCodeCore(comparer);
}
///
/// Returns a string that represents the value of this instance.
///
/// The string representation of this instance.
///
/// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7, Rest).
/// If any field value is , it is represented as .
///
public override string ToString()
{
IValueTupleInternal rest = Rest as IValueTupleInternal;
if (rest == null)
{
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")";
}
else
{
return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd();
}
}
string IValueTupleInternal.ToStringEnd()
{
IValueTupleInternal rest = Rest as IValueTupleInternal;
if (rest == null)
{
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")";
}
else
{
return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd();
}
}
///
/// The number of positions in this data structure.
///
int ITuple.Length
{
get
{
IValueTupleInternal rest = Rest as IValueTupleInternal;
return rest == null ? 8 : 7 + 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;
}
IValueTupleInternal rest = Rest as IValueTupleInternal;
if (rest == null)
{
if (index == 7)
{
return Rest;
}
throw new IndexOutOfRangeException();
}
return rest[index - 7];
}
}
}
}