diff --git a/src/System.ValueTuple/System.ValueTuple.sln b/src/System.ValueTuple/System.ValueTuple.sln new file mode 100644 index 000000000..a42a52b15 --- /dev/null +++ b/src/System.ValueTuple/System.ValueTuple.sln @@ -0,0 +1,50 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.ValueTuple.Tests", "tests\System.ValueTuple.Tests.csproj", "{CBD5AE8D-8595-48E2-848F-1A3492A28FDB}" + ProjectSection(ProjectDependencies) = postProject + {4C2655DB-BD9E-4C86-83A6-744ECDDBDF29} = {4C2655DB-BD9E-4C86-83A6-744ECDDBDF29} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.ValueTuple", "src\System.ValueTuple.csproj", "{4C2655DB-BD9E-4C86-83A6-744ECDDBDF29}" + ProjectSection(ProjectDependencies) = postProject + {11AE73F7-3532-47B9-8FF6-B4F22D76456D} = {11AE73F7-3532-47B9-8FF6-B4F22D76456D} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.ValueTuple", "ref\System.ValueTuple.csproj", "{11AE73F7-3532-47B9-8FF6-B4F22D76456D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1A2F9F4A-A032-433E-B914-ADD5992BB178}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E107E9C1-E893-4E87-987E-04EF0DCEAEFD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2EDB-464B-9DF6-380BF4789AD4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CBD5AE8D-8595-48E2-848F-1A3492A28FDB}.Debug|Any CPU.ActiveCfg = netcoreapp-Debug|Any CPU + {CBD5AE8D-8595-48E2-848F-1A3492A28FDB}.Debug|Any CPU.Build.0 = netcoreapp-Debug|Any CPU + {CBD5AE8D-8595-48E2-848F-1A3492A28FDB}.Release|Any CPU.ActiveCfg = netcoreapp-Release|Any CPU + {CBD5AE8D-8595-48E2-848F-1A3492A28FDB}.Release|Any CPU.Build.0 = netcoreapp-Release|Any CPU + {4C2655DB-BD9E-4C86-83A6-744ECDDBDF29}.Debug|Any CPU.ActiveCfg = netcoreapp-Debug|Any CPU + {4C2655DB-BD9E-4C86-83A6-744ECDDBDF29}.Debug|Any CPU.Build.0 = netcoreapp-Debug|Any CPU + {4C2655DB-BD9E-4C86-83A6-744ECDDBDF29}.Release|Any CPU.ActiveCfg = netcoreapp-Release|Any CPU + {4C2655DB-BD9E-4C86-83A6-744ECDDBDF29}.Release|Any CPU.Build.0 = netcoreapp-Release|Any CPU + {11AE73F7-3532-47B9-8FF6-B4F22D76456D}.Debug|Any CPU.ActiveCfg = netcoreapp-Debug|Any CPU + {11AE73F7-3532-47B9-8FF6-B4F22D76456D}.Debug|Any CPU.Build.0 = netcoreapp-Debug|Any CPU + {11AE73F7-3532-47B9-8FF6-B4F22D76456D}.Release|Any CPU.ActiveCfg = netcoreapp-Release|Any CPU + {11AE73F7-3532-47B9-8FF6-B4F22D76456D}.Release|Any CPU.Build.0 = netcoreapp-Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {CBD5AE8D-8595-48E2-848F-1A3492A28FDB} = {1A2F9F4A-A032-433E-B914-ADD5992BB178} + {4C2655DB-BD9E-4C86-83A6-744ECDDBDF29} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD} + {11AE73F7-3532-47B9-8FF6-B4F22D76456D} = {2E666815-2EDB-464B-9DF6-380BF4789AD4} + EndGlobalSection +EndGlobal diff --git a/src/System.ValueTuple/dir.props b/src/System.ValueTuple/dir.props new file mode 100644 index 000000000..637f027be --- /dev/null +++ b/src/System.ValueTuple/dir.props @@ -0,0 +1,10 @@ + + + + + 4.0.3.0 + Open + true + true + + \ No newline at end of file diff --git a/src/System.ValueTuple/pkg/System.ValueTuple.pkgproj b/src/System.ValueTuple/pkg/System.ValueTuple.pkgproj new file mode 100644 index 000000000..405cb5152 --- /dev/null +++ b/src/System.ValueTuple/pkg/System.ValueTuple.pkgproj @@ -0,0 +1,15 @@ + + + + + + net45;netcore45;netcoreapp2.1;wp8;wpa81;$(AllXamarinFrameworks) + + + + + + + + + \ No newline at end of file diff --git a/src/System.ValueTuple/ref/Configurations.props b/src/System.ValueTuple/ref/Configurations.props new file mode 100644 index 000000000..c1545db6c --- /dev/null +++ b/src/System.ValueTuple/ref/Configurations.props @@ -0,0 +1,15 @@ + + + + + portable_net40+sl4+win8+wp8; + netfx; + net47; + + + $(PackageConfigurations); + netcoreapp; + uap; + + + diff --git a/src/System.ValueTuple/ref/System.Runtime.CompilerServices.ReferenceAssemblyAttribute.cs b/src/System.ValueTuple/ref/System.Runtime.CompilerServices.ReferenceAssemblyAttribute.cs new file mode 100644 index 000000000..60c6795f7 --- /dev/null +++ b/src/System.ValueTuple/ref/System.Runtime.CompilerServices.ReferenceAssemblyAttribute.cs @@ -0,0 +1,17 @@ +// 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. +// ------------------------------------------------------------------------------ + +namespace System.Runtime.CompilerServices +{ + using System; + + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] + internal sealed class ReferenceAssemblyAttribute : Attribute + { + internal ReferenceAssemblyAttribute() { } + internal ReferenceAssemblyAttribute(String description) { throw null; } + internal String Description { get { throw null; } } + } +} \ No newline at end of file diff --git a/src/System.ValueTuple/ref/System.Security.AllowPartiallyTrustedCallersAttribute.cs b/src/System.ValueTuple/ref/System.Security.AllowPartiallyTrustedCallersAttribute.cs new file mode 100644 index 000000000..be03c088f --- /dev/null +++ b/src/System.ValueTuple/ref/System.Security.AllowPartiallyTrustedCallersAttribute.cs @@ -0,0 +1,25 @@ +// 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. +// ------------------------------------------------------------------------------ + +namespace System.Security +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] + sealed internal class AllowPartiallyTrustedCallersAttribute : System.Attribute + { + internal AllowPartiallyTrustedCallersAttribute() { throw null; } + + internal PartialTrustVisibilityLevel PartialTrustVisibilityLevel + { + get { throw null; } + set { throw null; } + } + } + + internal enum PartialTrustVisibilityLevel + { + VisibleToAllHosts = 0, + NotVisibleByDefault = 1 + } +} diff --git a/src/System.ValueTuple/ref/System.ValueTuple.TypeForwards.cs b/src/System.ValueTuple/ref/System.ValueTuple.TypeForwards.cs new file mode 100644 index 000000000..9cc9fc667 --- /dev/null +++ b/src/System.ValueTuple/ref/System.ValueTuple.TypeForwards.cs @@ -0,0 +1,15 @@ +// 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. + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,,>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ValueTuple<,,,,,,,>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.TupleExtensions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.TupleElementNamesAttribute))] diff --git a/src/System.ValueTuple/ref/System.ValueTuple.cs b/src/System.ValueTuple/ref/System.ValueTuple.cs new file mode 100644 index 000000000..0d8b4118e --- /dev/null +++ b/src/System.ValueTuple/ref/System.ValueTuple.cs @@ -0,0 +1,681 @@ +// 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. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the http://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +namespace System +{ + public struct ValueTuple + : IEquatable, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable + { + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + public static ValueTuple Create() { throw null; } + public static ValueTuple Create(T1 item1) { throw null; } + public static ValueTuple Create(T1 item1, T2 item2) { throw null; } + public static ValueTuple Create(T1 item1, T2 item2, T3 item3) { throw null; } + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) { throw null; } + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { throw null; } + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { throw null; } + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { throw null; } + public static ValueTuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { throw null; } + } + public struct ValueTuple + : IEquatable>, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable> + { + public T1 Item1; + public ValueTuple(T1 item1) { throw null; } + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + } + [Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable> + { + public T1 Item1; + public T2 Item2; + public ValueTuple(T1 item1, T2 item2) { throw null; } + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + } + [Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable> + { + public T1 Item1; + public T2 Item2; + public T3 Item3; + public ValueTuple(T1 item1, T2 item2, T3 item3) { throw null; } + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + } + [Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable> + { + public T1 Item1; + public T2 Item2; + public T3 Item3; + public T4 Item4; + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4) { throw null; } + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + } + [Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable> + { + public T1 Item1; + public T2 Item2; + public T3 Item3; + public T4 Item4; + public T5 Item5; + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { throw null; } + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + } + [Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable> + { + public T1 Item1; + public T2 Item2; + public T3 Item3; + public T4 Item4; + public T5 Item5; + public T6 Item6; + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { throw null; } + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + } + [Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable> + { + public T1 Item1; + public T2 Item2; + public T3 Item3; + public T4 Item4; + public T5 Item5; + public T6 Item6; + public T7 Item7; + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { throw null; } + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + } + [Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, Collections.IStructuralEquatable, Collections.IStructuralComparable, IComparable, IComparable> + where TRest : struct + { + public T1 Item1; + public T2 Item2; + public T3 Item3; + public T4 Item4; + public T5 Item5; + public T6 Item6; + public T7 Item7; + public TRest Rest; + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { throw null; } + public override bool Equals(object obj) { throw null; } + public bool Equals(ValueTuple other) { throw null; } + bool Collections.IStructuralEquatable.Equals(object other, Collections.IEqualityComparer comparer) { throw null; } + int IComparable.CompareTo(object other) { throw null; } + public int CompareTo(ValueTuple other) { throw null; } + int Collections.IStructuralComparable.CompareTo(object other, Collections.IComparer comparer) { throw null; } + public override int GetHashCode() { throw null; } + int Collections.IStructuralEquatable.GetHashCode(Collections.IEqualityComparer comparer) { throw null; } + public override string ToString() { throw null; } + } +} + +namespace System +{ + using System.ComponentModel; + public static class TupleExtensions + { + #region Deconstruct + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20) + { + throw null; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20, out T21 item21) + { + throw null; + } + #endregion + + #region ToValueTuple + public static ValueTuple + ToValueTuple( + this Tuple value) + { + throw null; + } + + public static ValueTuple + ToValueTuple( + this Tuple value) + { + throw null; + } + + public static ValueTuple + ToValueTuple( + this Tuple value) + { + throw null; + } + + public static ValueTuple + ToValueTuple( + this Tuple value) + { + throw null; + } + + public static ValueTuple + ToValueTuple( + this Tuple value) + { + throw null; + } + + public static ValueTuple + ToValueTuple( + this Tuple value) + { + throw null; + } + + public static ValueTuple + ToValueTuple( + this Tuple value) + { + throw null; + } + + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + throw null; + } + + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + throw null; + } + + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + throw null; + } + + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + throw null; + } + + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + throw null; + } + + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + throw null; + } + + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + throw null; + } + + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + throw null; + } + + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + throw null; + } + + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + throw null; + } + + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + throw null; + } + + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + throw null; + } + + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + throw null; + } + + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + throw null; + } + #endregion + + #region ToTuple + public static Tuple + ToTuple( + this ValueTuple value) + { + throw null; + } + + public static Tuple + ToTuple( + this ValueTuple value) + { + throw null; + } + + public static Tuple + ToTuple( + this ValueTuple value) + { + throw null; + } + + public static Tuple + ToTuple( + this ValueTuple value) + { + throw null; + } + + public static Tuple + ToTuple( + this ValueTuple value) + { + throw null; + } + + public static Tuple + ToTuple( + this ValueTuple value) + { + throw null; + } + + public static Tuple + ToTuple( + this ValueTuple value) + { + throw null; + } + + public static Tuple> + ToTuple( + this ValueTuple> value) + { + throw null; + } + + public static Tuple> + ToTuple( + this ValueTuple> value) + { + throw null; + } + + public static Tuple> + ToTuple( + this ValueTuple> value) + { + throw null; + } + + public static Tuple> + ToTuple( + this ValueTuple> value) + { + throw null; + } + + public static Tuple> + ToTuple( + this ValueTuple> value) + { + throw null; + } + + public static Tuple> + ToTuple( + this ValueTuple> value) + { + throw null; + } + + public static Tuple> + ToTuple( + this ValueTuple> value) + { + throw null; + } + + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + throw null; + } + + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + throw null; + } + + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + throw null; + } + + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + throw null; + } + + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + throw null; + } + + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + throw null; + } + + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + throw null; + } + #endregion + + private static ValueTuple CreateLong(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct => + new ValueTuple(item1, item2, item3, item4, item5, item6, item7, rest); + + private static Tuple CreateLongRef(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) => + new Tuple(item1, item2, item3, item4, item5, item6, item7, rest); + } +} + +namespace System.Runtime.CompilerServices +{ + using System.Collections.Generic; + [CLSCompliant(false)] + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Event)] + public sealed class TupleElementNamesAttribute : Attribute + { + public TupleElementNamesAttribute(string[] transformNames) { throw null; } + public IList TransformNames { get { throw null; } } + } +} diff --git a/src/System.ValueTuple/ref/System.ValueTuple.csproj b/src/System.ValueTuple/ref/System.ValueTuple.csproj new file mode 100644 index 000000000..888a39f5a --- /dev/null +++ b/src/System.ValueTuple/ref/System.ValueTuple.csproj @@ -0,0 +1,48 @@ + + + + + {11AE73F7-3532-47B9-8FF6-B4F22D76456D} + System + + 4.0.3.0 + + + + + + + + + + + + + + + + + + + + + Common\System\Reflection\AssemblyMetadataAttribute.cs + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/System.ValueTuple/src/AssemblyInfo.cs b/src/System.ValueTuple/src/AssemblyInfo.cs new file mode 100644 index 000000000..f790e088a --- /dev/null +++ b/src/System.ValueTuple/src/AssemblyInfo.cs @@ -0,0 +1,7 @@ +// 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.Security; + +[assembly: AllowPartiallyTrustedCallers] \ No newline at end of file diff --git a/src/System.ValueTuple/src/Configurations.props b/src/System.ValueTuple/src/Configurations.props new file mode 100644 index 000000000..2081e9167 --- /dev/null +++ b/src/System.ValueTuple/src/Configurations.props @@ -0,0 +1,16 @@ + + + + + portable_net40+sl4+win8+wp8; + netstandard1.0; + netfx; + net47; + + + $(PackageConfigurations); + netcoreapp; + uap-Windows_NT; + + + diff --git a/src/System.ValueTuple/src/Resources/Strings.resx b/src/System.ValueTuple/src/Resources/Strings.resx new file mode 100644 index 000000000..8d94b500f --- /dev/null +++ b/src/System.ValueTuple/src/Resources/Strings.resx @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The parameter should be a ValueTuple type of appropriate arity. + + + The TRest type argument of ValueTuple`8 must be a ValueTuple. + + diff --git a/src/System.ValueTuple/src/System.ValueTuple.csproj b/src/System.ValueTuple/src/System.ValueTuple.csproj new file mode 100644 index 000000000..df0bb72a5 --- /dev/null +++ b/src/System.ValueTuple/src/System.ValueTuple.csproj @@ -0,0 +1,58 @@ + + + + + + {4C2655DB-BD9E-4C86-83A6-744ECDDBDF29} + $(OutputPath)$(MSBuildProjectName).xml + true + false + + false + + + + + + + + + + + + + + + + System + + + + + + + Common\System\Numerics\Hashing\HashHelpers.cs + + + + + + + + + Common\System\Reflection\AssemblyMetadataAttribute.cs + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/System.ValueTuple/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs b/src/System.ValueTuple/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs new file mode 100644 index 000000000..25ee7280c --- /dev/null +++ b/src/System.ValueTuple/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs @@ -0,0 +1,57 @@ +// 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.Generic; + +namespace System.Runtime.CompilerServices +{ + /// + /// Indicates that the use of on a member is meant to be treated as a tuple with element names. + /// + [CLSCompliant(false)] + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Event )] + public sealed class TupleElementNamesAttribute : Attribute + { + private readonly string[] _transformNames; + + /// + /// Initializes a new instance of the class. + /// + /// + /// Specifies, in a pre-order depth-first traversal of a type's + /// construction, which occurrences are + /// meant to carry element names. + /// + /// + /// This constructor is meant to be used on types that contain an + /// instantiation of that contains + /// element names. For instance, if C is a generic type with + /// two type parameters, then a use of the constructed type C{, might be intended to + /// treat the first type argument as a tuple with element names and the + /// second as a tuple without element names. In which case, the + /// appropriate attribute specification should use a + /// transformNames value of { "name1", "name2", null, null, + /// null }. + /// + public TupleElementNamesAttribute(string[] transformNames) + { + if (transformNames == null) + { + throw new ArgumentNullException(nameof(transformNames)); + } + + _transformNames = transformNames; + } + + /// + /// Specifies, in a pre-order depth-first traversal of a type's + /// construction, which elements are + /// meant to carry element names. + /// + public IList TransformNames => _transformNames; + } +} diff --git a/src/System.ValueTuple/src/System/ValueTuple/TupleExtensions.cs b/src/System.ValueTuple/src/System/ValueTuple/TupleExtensions.cs new file mode 100644 index 000000000..096df9571 --- /dev/null +++ b/src/System.ValueTuple/src/System/ValueTuple/TupleExtensions.cs @@ -0,0 +1,929 @@ +// 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.ComponentModel; + +namespace System +{ + /// + /// Provides extension methods for instances to interop with C# tuples features (deconstruction syntax, converting from and to ). + /// + public static class TupleExtensions + { + #region Deconstruct + /// + /// Deconstruct a properly nested with 1 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1) + { + item1 = value.Item1; + } + + /// + /// Deconstruct a properly nested with 2 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2) + { + item1 = value.Item1; + item2 = value.Item2; + } + + /// + /// Deconstruct a properly nested with 3 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + } + + /// + /// Deconstruct a properly nested with 4 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + } + + /// + /// Deconstruct a properly nested with 5 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + } + + /// + /// Deconstruct a properly nested with 6 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + } + + /// + /// Deconstruct a properly nested with 7 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + } + + /// + /// Deconstruct a properly nested with 8 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + } + + /// + /// Deconstruct a properly nested with 9 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + } + + /// + /// Deconstruct a properly nested with 10 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + } + + /// + /// Deconstruct a properly nested with 11 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + } + + /// + /// Deconstruct a properly nested with 12 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + } + + /// + /// Deconstruct a properly nested with 13 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + } + + /// + /// Deconstruct a properly nested with 14 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + item14 = value.Rest.Item7; + } + + /// + /// Deconstruct a properly nested with 15 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + item14 = value.Rest.Item7; + item15 = value.Rest.Rest.Item1; + } + + /// + /// Deconstruct a properly nested with 16 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + item14 = value.Rest.Item7; + item15 = value.Rest.Rest.Item1; + item16 = value.Rest.Rest.Item2; + } + + /// + /// Deconstruct a properly nested with 17 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + item14 = value.Rest.Item7; + item15 = value.Rest.Rest.Item1; + item16 = value.Rest.Rest.Item2; + item17 = value.Rest.Rest.Item3; + } + + /// + /// Deconstruct a properly nested with 18 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + item14 = value.Rest.Item7; + item15 = value.Rest.Rest.Item1; + item16 = value.Rest.Rest.Item2; + item17 = value.Rest.Rest.Item3; + item18 = value.Rest.Rest.Item4; + } + + /// + /// Deconstruct a properly nested with 19 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + item14 = value.Rest.Item7; + item15 = value.Rest.Rest.Item1; + item16 = value.Rest.Rest.Item2; + item17 = value.Rest.Rest.Item3; + item18 = value.Rest.Rest.Item4; + item19 = value.Rest.Rest.Item5; + } + + /// + /// Deconstruct a properly nested with 20 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + item14 = value.Rest.Item7; + item15 = value.Rest.Rest.Item1; + item16 = value.Rest.Rest.Item2; + item17 = value.Rest.Rest.Item3; + item18 = value.Rest.Rest.Item4; + item19 = value.Rest.Rest.Item5; + item20 = value.Rest.Rest.Item6; + } + + /// + /// Deconstruct a properly nested with 21 elements. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void Deconstruct( + this Tuple>> value, + out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20, out T21 item21) + { + item1 = value.Item1; + item2 = value.Item2; + item3 = value.Item3; + item4 = value.Item4; + item5 = value.Item5; + item6 = value.Item6; + item7 = value.Item7; + item8 = value.Rest.Item1; + item9 = value.Rest.Item2; + item10 = value.Rest.Item3; + item11 = value.Rest.Item4; + item12 = value.Rest.Item5; + item13 = value.Rest.Item6; + item14 = value.Rest.Item7; + item15 = value.Rest.Rest.Item1; + item16 = value.Rest.Rest.Item2; + item17 = value.Rest.Rest.Item3; + item18 = value.Rest.Rest.Item4; + item19 = value.Rest.Rest.Item5; + item20 = value.Rest.Rest.Item6; + item21 = value.Rest.Rest.Item7; + } + #endregion + + #region ToValueTuple + /// + /// Make a properly nested from a properly nested with 1 element. + /// + public static ValueTuple + ToValueTuple( + this Tuple value) + { + return ValueTuple.Create(value.Item1); + } + + /// + /// Make a properly nested from a properly nested with 2 elements. + /// + public static ValueTuple + ToValueTuple( + this Tuple value) + { + return ValueTuple.Create(value.Item1, value.Item2); + } + + /// + /// Make a properly nested from a properly nested with 3 elements. + /// + public static ValueTuple + ToValueTuple( + this Tuple value) + { + return ValueTuple.Create(value.Item1, value.Item2, value.Item3); + } + + /// + /// Make a properly nested from a properly nested with 4 elements. + /// + public static ValueTuple + ToValueTuple( + this Tuple value) + { + return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4); + } + + /// + /// Make a properly nested from a properly nested with 5 elements. + /// + public static ValueTuple + ToValueTuple( + this Tuple value) + { + return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5); + } + + /// + /// Make a properly nested from a properly nested with 6 elements. + /// + public static ValueTuple + ToValueTuple( + this Tuple value) + { + return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6); + } + + /// + /// Make a properly nested from a properly nested with 7 elements. + /// + public static ValueTuple + ToValueTuple( + this Tuple value) + { + return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7); + } + + /// + /// Make a properly nested from a properly nested with 8 elements. + /// + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + ValueTuple.Create(value.Rest.Item1)); + } + + /// + /// Make a properly nested from a properly nested with 9 elements. + /// + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + ValueTuple.Create(value.Rest.Item1, value.Rest.Item2)); + } + + /// + /// Make a properly nested from a properly nested with 10 elements. + /// + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3)); + } + + /// + /// Make a properly nested from a properly nested with 11 elements. + /// + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4)); + } + + /// + /// Make a properly nested from a properly nested with 12 elements. + /// + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5)); + } + + /// + /// Make a properly nested from a properly nested with 13 elements. + /// + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6)); + } + + /// + /// Make a properly nested from a properly nested with 14 elements. + /// + public static ValueTuple> + ToValueTuple( + this Tuple> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7)); + } + + /// + /// Make a properly nested from a properly nested with 15 elements. + /// + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + ValueTuple.Create(value.Rest.Rest.Item1))); + } + + /// + /// Make a properly nested from a properly nested with 16 elements. + /// + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2))); + } + + /// + /// Make a properly nested from a properly nested with 17 elements. + /// + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3))); + } + + /// + /// Make a properly nested from a properly nested with 18 elements. + /// + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4))); + } + + /// + /// Make a properly nested from a properly nested with 19 elements. + /// + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5))); + } + + /// + /// Make a properly nested from a properly nested with 20 elements. + /// + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6))); + } + + /// + /// Make a properly nested from a properly nested with 21 elements. + /// + public static ValueTuple>> + ToValueTuple( + this Tuple>> value) + { + return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7))); + } + #endregion + + #region ToTuple + /// + /// Make a properly nested from a properly nested with 1 element. + /// + public static Tuple + ToTuple( + this ValueTuple value) + { + return Tuple.Create(value.Item1); + } + + /// + /// Make a properly nested from a properly nested with 2 elements. + /// + public static Tuple + ToTuple( + this ValueTuple value) + { + return Tuple.Create(value.Item1, value.Item2); + } + + /// + /// Make a properly nested from a properly nested with 3 elements. + /// + public static Tuple + ToTuple( + this ValueTuple value) + { + return Tuple.Create(value.Item1, value.Item2, value.Item3); + } + + /// + /// Make a properly nested from a properly nested with 4 elements. + /// + public static Tuple + ToTuple( + this ValueTuple value) + { + return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4); + } + + /// + /// Make a properly nested from a properly nested with 5 elements. + /// + public static Tuple + ToTuple( + this ValueTuple value) + { + return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5); + } + + /// + /// Make a properly nested from a properly nested with 6 elements. + /// + public static Tuple + ToTuple( + this ValueTuple value) + { + return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6); + } + + /// + /// Make a properly nested from a properly nested with 7 elements. + /// + public static Tuple + ToTuple( + this ValueTuple value) + { + return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7); + } + + /// + /// Make a properly nested from a properly nested with 8 elements. + /// + public static Tuple> + ToTuple( + this ValueTuple> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + Tuple.Create(value.Rest.Item1)); + } + + /// + /// Make a properly nested from a properly nested with 9 elements. + /// + public static Tuple> + ToTuple( + this ValueTuple> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + Tuple.Create(value.Rest.Item1, value.Rest.Item2)); + } + + /// + /// Make a properly nested from a properly nested with 10 elements. + /// + public static Tuple> + ToTuple( + this ValueTuple> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3)); + } + + /// + /// Make a properly nested from a properly nested with 11 elements. + /// + public static Tuple> + ToTuple( + this ValueTuple> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4)); + } + + /// + /// Make a properly nested from a properly nested with 12 elements. + /// + public static Tuple> + ToTuple( + this ValueTuple> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5)); + } + + /// + /// Make a properly nested from a properly nested with 13 elements. + /// + public static Tuple> + ToTuple( + this ValueTuple> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6)); + } + + /// + /// Make a properly nested from a properly nested with 14 elements. + /// + public static Tuple> + ToTuple( + this ValueTuple> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7)); + } + + /// + /// Make a properly nested from a properly nested with 15 elements. + /// + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + Tuple.Create(value.Rest.Rest.Item1))); + } + + /// + /// Make a properly nested from a properly nested with 16 elements. + /// + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2))); + } + + /// + /// Make a properly nested from a properly nested with 17 elements. + /// + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3))); + } + + /// + /// Make a properly nested from a properly nested with 18 elements. + /// + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4))); + } + + /// + /// Make a properly nested from a properly nested with 19 elements. + /// + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5))); + } + + /// + /// Make a properly nested from a properly nested with 20 elements. + /// + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6))); + } + + /// + /// Make a properly nested from a properly nested with 21 elements. + /// + public static Tuple>> + ToTuple( + this ValueTuple>> value) + { + return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, + CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, + Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7))); + } + #endregion + + private static ValueTuple CreateLong(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct => + new ValueTuple(item1, item2, item3, item4, item5, item6, item7, rest); + + private static Tuple CreateLongRef(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) => + new Tuple(item1, item2, item3, item4, item5, item6, item7, rest); + } +} \ No newline at end of file diff --git a/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs b/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs new file mode 100644 index 000000000..e05248fa7 --- /dev/null +++ b/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs @@ -0,0 +1,2124 @@ +// 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; +using System.Numerics.Hashing; +using System.Runtime.InteropServices; + +namespace System +{ + /// + /// Helper so we can call some tuple methods recursively without knowing the underlying types. + /// + internal interface ITupleInternal + { + int GetHashCode(IEqualityComparer comparer); + int Size { get; } + 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. + /// + public struct ValueTuple + : IEquatable, IStructuralEquatable, IStructuralComparable, IComparable, IComparable, ITupleInternal + { + /// + /// 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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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 ITupleInternal.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 ITupleInternal.ToStringEnd() + { + return ")"; + } + + int ITupleInternal.Size => 0; + + /// 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. + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal + { + private static readonly EqualityComparer s_t1Comparer = EqualityComparer.Default; + + /// + /// 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 s_t1Comparer.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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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 s_t1Comparer.GetHashCode(Item1); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return comparer.GetHashCode(Item1); + } + + int ITupleInternal.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 ITupleInternal.ToStringEnd() + { + return Item1?.ToString() + ")"; + } + + int ITupleInternal.Size => 1; + } + + /// + /// 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. + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal + { + private static readonly EqualityComparer s_t1Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t2Comparer = EqualityComparer.Default; + + /// + /// The current instance's first component. + /// + public T1 Item1; + + /// + /// The current instance's second 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 s_t1Comparer.Equals(Item1, other.Item1) + && s_t2Comparer.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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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(s_t1Comparer.GetHashCode(Item1), + s_t2Comparer.GetHashCode(Item2)); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), + comparer.GetHashCode(Item2)); + } + + int ITupleInternal.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 ITupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ")"; + } + + int ITupleInternal.Size => 2; + } + + /// + /// 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. + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal + { + private static readonly EqualityComparer s_t1Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t2Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t3Comparer = EqualityComparer.Default; + + /// + /// 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 s_t1Comparer.Equals(Item1, other.Item1) + && s_t2Comparer.Equals(Item2, other.Item2) + && s_t3Comparer.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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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(s_t1Comparer.GetHashCode(Item1), + s_t2Comparer.GetHashCode(Item2), + s_t3Comparer.GetHashCode(Item3)); + } + + 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 ITupleInternal.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 ITupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; + } + + int ITupleInternal.Size => 3; + } + + /// + /// 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. + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal + { + private static readonly EqualityComparer s_t1Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t2Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t3Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t4Comparer = EqualityComparer.Default; + + /// + /// 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 s_t1Comparer.Equals(Item1, other.Item1) + && s_t2Comparer.Equals(Item2, other.Item2) + && s_t3Comparer.Equals(Item3, other.Item3) + && s_t4Comparer.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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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(s_t1Comparer.GetHashCode(Item1), + s_t2Comparer.GetHashCode(Item2), + s_t3Comparer.GetHashCode(Item3), + s_t4Comparer.GetHashCode(Item4)); + } + + 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 ITupleInternal.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 ITupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; + } + + int ITupleInternal.Size => 4; + } + + /// + /// 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. + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal + { + private static readonly EqualityComparer s_t1Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t2Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t3Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t4Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t5Comparer = EqualityComparer.Default; + + /// + /// 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 s_t1Comparer.Equals(Item1, other.Item1) + && s_t2Comparer.Equals(Item2, other.Item2) + && s_t3Comparer.Equals(Item3, other.Item3) + && s_t4Comparer.Equals(Item4, other.Item4) + && s_t5Comparer.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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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(s_t1Comparer.GetHashCode(Item1), + s_t2Comparer.GetHashCode(Item2), + s_t3Comparer.GetHashCode(Item3), + s_t4Comparer.GetHashCode(Item4), + s_t5Comparer.GetHashCode(Item5)); + } + + 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 ITupleInternal.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 ITupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; + } + + int ITupleInternal.Size => 5; + } + + /// + /// 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. + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal + { + private static readonly EqualityComparer s_t1Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t2Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t3Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t4Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t5Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t6Comparer = EqualityComparer.Default; + + /// + /// 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 s_t1Comparer.Equals(Item1, other.Item1) + && s_t2Comparer.Equals(Item2, other.Item2) + && s_t3Comparer.Equals(Item3, other.Item3) + && s_t4Comparer.Equals(Item4, other.Item4) + && s_t5Comparer.Equals(Item5, other.Item5) + && s_t6Comparer.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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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(s_t1Comparer.GetHashCode(Item1), + s_t2Comparer.GetHashCode(Item2), + s_t3Comparer.GetHashCode(Item3), + s_t4Comparer.GetHashCode(Item4), + s_t5Comparer.GetHashCode(Item5), + s_t6Comparer.GetHashCode(Item6)); + } + + 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 ITupleInternal.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 ITupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; + } + + int ITupleInternal.Size => 6; + } + + /// + /// 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. + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal + { + private static readonly EqualityComparer s_t1Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t2Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t3Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t4Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t5Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t6Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t7Comparer = EqualityComparer.Default; + + /// + /// 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 s_t1Comparer.Equals(Item1, other.Item1) + && s_t2Comparer.Equals(Item2, other.Item2) + && s_t3Comparer.Equals(Item3, other.Item3) + && s_t4Comparer.Equals(Item4, other.Item4) + && s_t5Comparer.Equals(Item5, other.Item5) + && s_t6Comparer.Equals(Item6, other.Item6) + && s_t7Comparer.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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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(s_t1Comparer.GetHashCode(Item1), + s_t2Comparer.GetHashCode(Item2), + s_t3Comparer.GetHashCode(Item3), + s_t4Comparer.GetHashCode(Item4), + s_t5Comparer.GetHashCode(Item5), + s_t6Comparer.GetHashCode(Item6), + s_t7Comparer.GetHashCode(Item7)); + } + + 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 ITupleInternal.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 ITupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; + } + + int ITupleInternal.Size => 7; + } + + /// + /// 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. + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal + where TRest : struct + { + private static readonly EqualityComparer s_t1Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t2Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t3Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t4Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t5Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t6Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_t7Comparer = EqualityComparer.Default; + private static readonly EqualityComparer s_tRestComparer = EqualityComparer.Default; + + /// + /// 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 ITupleInternal)) + { + 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 s_t1Comparer.Equals(Item1, other.Item1) + && s_t2Comparer.Equals(Item2, other.Item2) + && s_t3Comparer.Equals(Item3, other.Item3) + && s_t4Comparer.Equals(Item4, other.Item4) + && s_t5Comparer.Equals(Item5, other.Item5) + && s_t6Comparer.Equals(Item6, other.Item6) + && s_t7Comparer.Equals(Item7, other.Item7) + && s_tRestComparer.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.ArgumentException_ValueTupleIncorrectType, 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.ArgumentException_ValueTupleIncorrectType, 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 + ITupleInternal rest = Rest as ITupleInternal; + if (rest == null) + { + return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), + s_t2Comparer.GetHashCode(Item2), + s_t3Comparer.GetHashCode(Item3), + s_t4Comparer.GetHashCode(Item4), + s_t5Comparer.GetHashCode(Item5), + s_t6Comparer.GetHashCode(Item6), + s_t7Comparer.GetHashCode(Item7)); + } + + int size = rest.Size; + 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(s_t7Comparer.GetHashCode(Item7), + rest.GetHashCode()); + case 2: + return ValueTuple.CombineHashCodes(s_t6Comparer.GetHashCode(Item6), + s_t7Comparer.GetHashCode(Item7), + rest.GetHashCode()); + case 3: + return ValueTuple.CombineHashCodes(s_t5Comparer.GetHashCode(Item5), + s_t6Comparer.GetHashCode(Item6), + s_t7Comparer.GetHashCode(Item7), + rest.GetHashCode()); + case 4: + return ValueTuple.CombineHashCodes(s_t4Comparer.GetHashCode(Item4), + s_t5Comparer.GetHashCode(Item5), + s_t6Comparer.GetHashCode(Item6), + s_t7Comparer.GetHashCode(Item7), + rest.GetHashCode()); + case 5: + return ValueTuple.CombineHashCodes(s_t3Comparer.GetHashCode(Item3), + s_t4Comparer.GetHashCode(Item4), + s_t5Comparer.GetHashCode(Item5), + s_t6Comparer.GetHashCode(Item6), + s_t7Comparer.GetHashCode(Item7), + rest.GetHashCode()); + case 6: + return ValueTuple.CombineHashCodes(s_t2Comparer.GetHashCode(Item2), + s_t3Comparer.GetHashCode(Item3), + s_t4Comparer.GetHashCode(Item4), + s_t5Comparer.GetHashCode(Item5), + s_t6Comparer.GetHashCode(Item6), + s_t7Comparer.GetHashCode(Item7), + rest.GetHashCode()); + case 7: + case 8: + return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), + s_t2Comparer.GetHashCode(Item2), + s_t3Comparer.GetHashCode(Item3), + s_t4Comparer.GetHashCode(Item4), + s_t5Comparer.GetHashCode(Item5), + s_t6Comparer.GetHashCode(Item6), + s_t7Comparer.GetHashCode(Item7), + rest.GetHashCode()); + } + + Debug.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 + ITupleInternal rest = Rest as ITupleInternal; + 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.Size; + 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)); + } + + Debug.Assert(false, "Missed all cases for computing ValueTuple hash code"); + return -1; + } + + int ITupleInternal.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() + { + ITupleInternal rest = Rest as ITupleInternal; + 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 ITupleInternal.ToStringEnd() + { + ITupleInternal rest = Rest as ITupleInternal; + 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(); + } + } + + int ITupleInternal.Size + { + get + { + ITupleInternal rest = Rest as ITupleInternal; + return rest == null ? 8 : 7 + rest.Size; + } + } + } +} diff --git a/src/System.ValueTuple/tests/Configurations.props b/src/System.ValueTuple/tests/Configurations.props new file mode 100644 index 000000000..8b803e077 --- /dev/null +++ b/src/System.ValueTuple/tests/Configurations.props @@ -0,0 +1,9 @@ + + + + + netcoreapp; + netstandard; + + + \ No newline at end of file diff --git a/src/System.ValueTuple/tests/ExtensionsTests.cs b/src/System.ValueTuple/tests/ExtensionsTests.cs new file mode 100644 index 000000000..7f05b32ae --- /dev/null +++ b/src/System.ValueTuple/tests/ExtensionsTests.cs @@ -0,0 +1,703 @@ +// 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 Xunit; + +namespace System.Tests +{ + public class ExtensionsTests + { + #region Deconstruct + [Fact] + public static void Deconstruct1() + { + var tuple = Tuple.Create(1); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1); + Assert.Equal("1", h.ToString()); + } + + [Fact] + public static void Deconstruct2() + { + var tuple = Tuple.Create(1, 2); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2); + Assert.Equal("1 2", h.ToString()); + } + + [Fact] + public static void Deconstruct3() + { + var tuple = Tuple.Create(1, 2, 3); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3); + Assert.Equal("1 2 3", h.ToString()); + } + + [Fact] + public static void Deconstruct4() + { + var tuple = Tuple.Create(1, 2, 3, 4); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4); + Assert.Equal("1 2 3 4", h.ToString()); + } + + [Fact] + public static void Deconstruct5() + { + var tuple = Tuple.Create(1, 2, 3, 4, 5); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5); + Assert.Equal("1 2 3 4 5", h.ToString()); + } + + [Fact] + public static void Deconstruct6() + { + var tuple = Tuple.Create(1, 2, 3, 4, 5, 6); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6); + Assert.Equal("1 2 3 4 5 6", h.ToString()); + } + + [Fact] + public static void Deconstruct7() + { + var tuple = Tuple.Create(1, 2, 3, 4, 5, 6, 7); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7); + Assert.Equal("1 2 3 4 5 6 7", h.ToString()); + } + + [Fact] + public static void Deconstruct8() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8)); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8); + Assert.Equal("1 2 3 4 5 6 7 8", h.ToString()); + } + + [Fact] + public static void Deconstruct9() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9)); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9); + Assert.Equal("1 2 3 4 5 6 7 8 9", h.ToString()); + } + + [Fact] + public static void Deconstruct10() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10)); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10); + Assert.Equal("1 2 3 4 5 6 7 8 9 10", h.ToString()); + } + + [Fact] + public static void Deconstruct11() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11)); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11", h.ToString()); + } + + [Fact] + public static void Deconstruct12() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12)); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12", h.ToString()); + } + + [Fact] + public static void Deconstruct13() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12, 13)); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13", h.ToString()); + } + + [Fact] + public static void Deconstruct14() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12, 13, 14)); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13, out h.x14); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13 14", h.ToString()); + } + + [Fact] + public static void Deconstruct15() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15))); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13, out h.x14, out h.x15); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15", h.ToString()); + } + + [Fact] + public static void Deconstruct16() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16))); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13, out h.x14, out h.x15, out h.x16); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16", h.ToString()); + } + + [Fact] + public static void Deconstruct17() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17))); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13, out h.x14, out h.x15, out h.x16, out h.x17); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17", h.ToString()); + } + + [Fact] + public static void Deconstruct18() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17, 18))); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13, out h.x14, out h.x15, out h.x16, out h.x17, out h.x18); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18", h.ToString()); + } + + [Fact] + public static void Deconstruct19() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17, 18, 19))); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13, out h.x14, out h.x15, out h.x16, out h.x17, out h.x18, out h.x19); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19", h.ToString()); + } + + [Fact] + public static void Deconstruct20() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17, 18, 19, 20))); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13, out h.x14, out h.x15, out h.x16, out h.x17, out h.x18, out h.x19, out h.x20); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20", h.ToString()); + } + + [Fact] + public static void Deconstruct21() + { + var tuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17, 18, 19, 20, 21))); + var h = new IntHolder(); + + tuple.Deconstruct(out h.x1, out h.x2, out h.x3, out h.x4, out h.x5, out h.x6, out h.x7, out h.x8, out h.x9, out h.x10, out h.x11, out h.x12, out h.x13, out h.x14, out h.x15, out h.x16, out h.x17, out h.x18, out h.x19, out h.x20, out h.x21); + Assert.Equal("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", h.ToString()); + } + #endregion + + #region ToTuple + [Fact] + public static void ConvertToRef1() + { + var refTuple = Tuple.Create(-1); + var valueTuple = ValueTuple.Create(1); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef2() + { + var refTuple = Tuple.Create(-1, -1); + var valueTuple = ValueTuple.Create(1, 2); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef3() + { + var refTuple = Tuple.Create(-1, -1, -1); + var valueTuple = ValueTuple.Create(1, 2, 3); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef4() + { + var refTuple = Tuple.Create(-1, -1, -1, -1); + var valueTuple = ValueTuple.Create(1, 2, 3, 4); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef5() + { + var refTuple = Tuple.Create(-1, -1, -1, -1, -1); + var valueTuple = ValueTuple.Create(1, 2, 3, 4, 5); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef6() + { + var refTuple = Tuple.Create(-1, -1, -1, -1, -1, -1); + var valueTuple = ValueTuple.Create(1, 2, 3, 4, 5, 6); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef7() + { + var refTuple = Tuple.Create(-1, -1, -1, -1, -1, -1, -1); + var valueTuple = ValueTuple.Create(1, 2, 3, 4, 5, 6, 7); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef8() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1)); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef9() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1)); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8, 9)); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef10() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1)); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8, 9, 10)); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef11() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1, -1)); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8, 9, 10, 11)); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef12() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1, -1, -1)); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8, 9, 10, 11, 12)); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef13() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1, -1, -1, -1)); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8, 9, 10, 11, 12, 13)); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef14() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1, -1, -1, -1, -1)); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8, 9, 10, 11, 12, 13, 14)); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef15() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1))); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLong(8, 9, 10, 11, 12, 13, 14, ValueTuple.Create(15))); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef16() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1))); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLong(8, 9, 10, 11, 12, 13, 14, ValueTuple.Create(15, 16))); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef17() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1))); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLong(8, 9, 10, 11, 12, 13, 14, ValueTuple.Create(15, 16, 17))); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef18() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1, -1))); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLong(8, 9, 10, 11, 12, 13, 14, ValueTuple.Create(15, 16, 17, 18))); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef19() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1, -1, -1))); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLong(8, 9, 10, 11, 12, 13, 14, ValueTuple.Create(15, 16, 17, 18, 19))); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef20() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1, -1, -1, -1))); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLong(8, 9, 10, 11, 12, 13, 14, ValueTuple.Create(15, 16, 17, 18, 19, 20))); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)", refTuple.ToString()); + } + + [Fact] + public static void ConvertToRef21() + { + var refTuple = ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLongRef(-1, -1, -1, -1, -1, -1, -1, Tuple.Create(-1, -1, -1, -1, -1, -1, -1))); + var valueTuple = ValueTupleTests.CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLong(8, 9, 10, 11, 12, 13, 14, ValueTuple.Create(15, 16, 17, 18, 19, 20, 21))); + + refTuple = valueTuple.ToTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)", refTuple.ToString()); + } + #endregion + + #region ToValue + [Fact] + public static void ConvertToValue1() + { + var valueTuple = ValueTuple.Create(-1); + var refTuple = Tuple.Create(1); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue2() + { + var valueTuple = ValueTuple.Create(-1, -1); + var refTuple = Tuple.Create(1, 2); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue3() + { + var valueTuple = ValueTuple.Create(-1, -1, -1); + var refTuple = Tuple.Create(1, 2, 3); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue4() + { + var valueTuple = ValueTuple.Create(-1, -1, -1, -1); + var refTuple = Tuple.Create(1, 2, 3, 4); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue5() + { + var valueTuple = ValueTuple.Create(-1, -1, -1, -1, -1); + var refTuple = Tuple.Create(1, 2, 3, 4, 5); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue6() + { + var valueTuple = ValueTuple.Create(-1, -1, -1, -1, -1, -1); + var refTuple = Tuple.Create(1, 2, 3, 4, 5, 6); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue7() + { + var valueTuple = ValueTuple.Create(-1, -1, -1, -1, -1, -1, -1); + var refTuple = Tuple.Create(1, 2, 3, 4, 5, 6, 7); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue8() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1)); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8)); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue9() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1)); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9)); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue10() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1)); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10)); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue11() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1, -1)); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11)); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue12() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1, -1, -1)); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12)); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue13() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1, -1, -1, -1)); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12, 13)); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue14() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1, -1, -1, -1, -1)); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12, 13, 14)); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue15() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1))); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15))); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue16() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1))); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16))); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue17() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1))); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17))); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue18() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1, -1))); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17, 18))); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue19() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1, -1, -1))); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17, 18, 19))); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue20() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1, -1, -1, -1))); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17, 18, 19, 20))); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)", valueTuple.ToString()); + } + + [Fact] + public static void ConvertToValue21() + { + var valueTuple = ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTupleTests.CreateLong(-1, -1, -1, -1, -1, -1, -1, ValueTuple.Create(-1, -1, -1, -1, -1, -1, -1))); + var refTuple = ValueTupleTests.CreateLongRef(1, 2, 3, 4, 5, 6, 7, ValueTupleTests.CreateLongRef(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16, 17, 18, 19, 20, 21))); + + valueTuple = refTuple.ToValueTuple(); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)", valueTuple.ToString()); + } + #endregion + + // Holds 21 int values + private struct IntHolder + { + public int x1; + public int x2; + public int x3; + public int x4; + public int x5; + public int x6; + public int x7; + public int x8; + public int x9; + public int x10; + public int x11; + public int x12; + public int x13; + public int x14; + public int x15; + public int x16; + public int x17; + public int x18; + public int x19; + public int x20; + public int x21; + + public override string ToString() + { + var builder = new StringBuilder(); + if (x1 > 0) { builder.Append(x1); } + if (x2 > 0) { builder.Append(" " + x2); } + if (x3 > 0) { builder.Append(" " + x3); } + if (x4 > 0) { builder.Append(" " + x4); } + if (x5 > 0) { builder.Append(" " + x5); } + if (x6 > 0) { builder.Append(" " + x6); } + if (x7 > 0) { builder.Append(" " + x7); } + if (x8 > 0) { builder.Append(" " + x8); } + if (x9 > 0) { builder.Append(" " + x9); } + if (x10 > 0) { builder.Append(" " + x10); } + if (x11 > 0) { builder.Append(" " + x11); } + if (x12 > 0) { builder.Append(" " + x12); } + if (x13 > 0) { builder.Append(" " + x13); } + if (x14 > 0) { builder.Append(" " + x14); } + if (x15 > 0) { builder.Append(" " + x15); } + if (x16 > 0) { builder.Append(" " + x16); } + if (x17 > 0) { builder.Append(" " + x17); } + if (x18 > 0) { builder.Append(" " + x18); } + if (x19 > 0) { builder.Append(" " + x19); } + if (x20 > 0) { builder.Append(" " + x20); } + if (x21 > 0) { builder.Append(" " + x21); } + + return builder.ToString(); + } + } + } +} \ No newline at end of file diff --git a/src/System.ValueTuple/tests/System.ValueTuple.Tests.csproj b/src/System.ValueTuple/tests/System.ValueTuple.Tests.csproj new file mode 100644 index 000000000..8d5ecfa52 --- /dev/null +++ b/src/System.ValueTuple/tests/System.ValueTuple.Tests.csproj @@ -0,0 +1,25 @@ + + + + + {CBD5AE8D-8595-48E2-848F-1A3492A28FDB} + $(DefineConstants);netcoreapp + + + 5 + + + + + + + + + + + + System\Runtime\Serialization\Formatters\BinaryFormatterHelpers.cs + + + + \ No newline at end of file diff --git a/src/System.ValueTuple/tests/TupleElementNamesTests.cs b/src/System.ValueTuple/tests/TupleElementNamesTests.cs new file mode 100644 index 000000000..78fe158c4 --- /dev/null +++ b/src/System.ValueTuple/tests/TupleElementNamesTests.cs @@ -0,0 +1,23 @@ +// 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.Runtime.CompilerServices; +using Xunit; + +namespace System.Tests +{ + public class TupleElementNamesAttributeTests + { + [Fact] + public static void Constructor() + { + var attribute = new TupleElementNamesAttribute(new string[] { "name1", "name2" }); + Assert.NotNull(attribute.TransformNames); + Assert.Equal(new string[] { "name1", "name2" }, attribute.TransformNames); + + Assert.Throws(() => new TupleElementNamesAttribute(null)); + } + } +} diff --git a/src/System.ValueTuple/tests/TupleTests.cs b/src/System.ValueTuple/tests/TupleTests.cs new file mode 100644 index 000000000..a180529fc --- /dev/null +++ b/src/System.ValueTuple/tests/TupleTests.cs @@ -0,0 +1,128 @@ +// 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. + +#if netcoreapp +using System; +using System.Collections; +using System.Collections.Generic; +using Xunit; +using System.Runtime.CompilerServices; + +namespace System.Tests +{ + public class TupleTests + { + [Fact] + public void Test() + { + // Subset of the Tuple tests related to ITuple + OneTuples(); + TwoTuples(); + ThreeTuples(); + FourTuples(); + FiveTuples(); + SixTuples(); + SevenTuples(); + EightTuples(); + } + + public static void OneTuples() + { + ITuple it = Tuple.Create(1); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Throws(() => it[1].ToString()); + } + + public static void TwoTuples() + { + ITuple it = Tuple.Create(1, 2); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Throws(() => it[2].ToString()); + } + + public static void ThreeTuples() + { + ITuple it = Tuple.Create(1, 2, 3); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Throws(() => it[3].ToString()); + } + + public static void FourTuples() + { + ITuple it = Tuple.Create(1, 2, 3, 4); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Throws(() => it[4].ToString()); + } + + public static void FiveTuples() + { + ITuple it = Tuple.Create(1, 2, 3, 4, 5); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Equal(5, it[4]); + Assert.Throws(() => it[5].ToString()); + } + + public static void SixTuples() + { + ITuple it = Tuple.Create(1, 2, 3, 4, 5, 6); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Equal(5, it[4]); + Assert.Equal(6, it[5]); + Assert.Throws(() => it[6].ToString()); + } + + public static void SevenTuples() + { + ITuple it = Tuple.Create(1, 2, 3, 4, 5, 6, 7); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Equal(5, it[4]); + Assert.Equal(6, it[5]); + Assert.Equal(7, it[6]); + Assert.Throws(() => it[7].ToString()); + } + + public static Tuple CreateLongRef(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) + { + return new Tuple(item1, item2, item3, item4, item5, item6, item7, rest); + } + + public static void EightTuples() + { + ITuple it = CreateLongRef(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8)); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Equal(5, it[4]); + Assert.Equal(6, it[5]); + Assert.Equal(7, it[6]); + Assert.Equal(8, it[7]); + Assert.Throws(() => it[8].ToString()); + } + } +} +#endif diff --git a/src/System.ValueTuple/tests/ValueTupleTests.cs b/src/System.ValueTuple/tests/ValueTupleTests.cs new file mode 100644 index 000000000..a3e82638d --- /dev/null +++ b/src/System.ValueTuple/tests/ValueTupleTests.cs @@ -0,0 +1,1360 @@ +// 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.Collections; +using System.Collections.Generic; +using Xunit; +#if netcoreapp +using System.Runtime.CompilerServices; +using System.Runtime.Serialization.Formatters.Tests; +#endif + +namespace System.Tests +{ + public class ValueTupleTests + { + private class ValueTupleTestDriver + { + private int _nItems; + + private readonly object valueTuple; + private readonly ValueTuple valueTuple0; + private readonly ValueTuple valueTuple1; + private readonly ValueTuple valueTuple2; + private readonly ValueTuple valueTuple3; + private readonly ValueTuple valueTuple4; + private readonly ValueTuple valueTuple5; + private readonly ValueTuple valueTuple6; + private readonly ValueTuple valueTuple7; + private readonly ValueTuple> valueTuple8; + private readonly ValueTuple> valueTuple9; + private readonly ValueTuple> valueTuple10; + + internal ValueTupleTestDriver(params object[] values) + { + if (values.Length > 10) + throw new ArgumentOutOfRangeException("values", "You must provide at most 10 values"); + + _nItems = values.Length; + switch (_nItems) + { + case 0: + valueTuple0 = ValueTuple.Create(); + valueTuple = valueTuple0; + break; + case 1: + valueTuple1 = ValueTuple.Create((T1)values[0]); + valueTuple = valueTuple1; + break; + case 2: + valueTuple2 = ValueTuple.Create((T1)values[0], (T2)values[1]); + valueTuple = valueTuple2; + break; + case 3: + valueTuple3 = ValueTuple.Create((T1)values[0], (T2)values[1], (T3)values[2]); + valueTuple = valueTuple3; + break; + case 4: + valueTuple4 = ValueTuple.Create((T1)values[0], (T2)values[1], (T3)values[2], (T4)values[3]); + valueTuple = valueTuple4; + break; + case 5: + valueTuple5 = ValueTuple.Create((T1)values[0], (T2)values[1], (T3)values[2], (T4)values[3], (T5)values[4]); + valueTuple = valueTuple5; + break; + case 6: + valueTuple6 = ValueTuple.Create((T1)values[0], (T2)values[1], (T3)values[2], (T4)values[3], + (T5)values[4], (T6)values[5]); + valueTuple = valueTuple6; + break; + case 7: + valueTuple7 = ValueTuple.Create((T1)values[0], (T2)values[1], (T3)values[2], (T4)values[3], + (T5)values[4], (T6)values[5], (T7)values[6]); + valueTuple = valueTuple7; + break; + case 8: + valueTuple8 = ValueTuple.Create((T1)values[0], (T2)values[1], (T3)values[2], (T4)values[3], + (T5)values[4], (T6)values[5], (T7)values[6], (T8)values[7]); + valueTuple = valueTuple8; + break; + case 9: + valueTuple9 = new ValueTuple>((T1)values[0], (T2)values[1], (T3)values[2], (T4)values[3], (T5)values[4], (T6)values[5], (T7)values[6], new ValueTuple((T8)values[7], (T9)values[8])); + valueTuple = valueTuple9; + break; + case 10: + valueTuple10 = new ValueTuple>((T1)values[0], (T2)values[1], (T3)values[2], (T4)values[3], (T5)values[4], (T6)values[5], (T7)values[6], new ValueTuple((T8)values[7], (T9)values[8], (T10)values[9])); + valueTuple = valueTuple10; + break; + } + } + + private void VerifyItem(int itemPos, object Item1, object Item2) + { + Assert.True(object.Equals(Item1, Item2)); + } + + public void TestConstructor(params object[] expectedValue) + { + if (expectedValue.Length != _nItems) + throw new ArgumentOutOfRangeException("expectedValues", "You must provide " + _nItems + " expectedvalues"); + + switch (_nItems) + { + case 0: + break; + case 1: + VerifyItem(1, valueTuple1.Item1, expectedValue[0]); + break; + case 2: + VerifyItem(1, valueTuple2.Item1, expectedValue[0]); + VerifyItem(2, valueTuple2.Item2, expectedValue[1]); + break; + case 3: + VerifyItem(1, valueTuple3.Item1, expectedValue[0]); + VerifyItem(2, valueTuple3.Item2, expectedValue[1]); + VerifyItem(3, valueTuple3.Item3, expectedValue[2]); + break; + case 4: + VerifyItem(1, valueTuple4.Item1, expectedValue[0]); + VerifyItem(2, valueTuple4.Item2, expectedValue[1]); + VerifyItem(3, valueTuple4.Item3, expectedValue[2]); + VerifyItem(4, valueTuple4.Item4, expectedValue[3]); + break; + case 5: + VerifyItem(1, valueTuple5.Item1, expectedValue[0]); + VerifyItem(2, valueTuple5.Item2, expectedValue[1]); + VerifyItem(3, valueTuple5.Item3, expectedValue[2]); + VerifyItem(4, valueTuple5.Item4, expectedValue[3]); + VerifyItem(5, valueTuple5.Item5, expectedValue[4]); + break; + case 6: + VerifyItem(1, valueTuple6.Item1, expectedValue[0]); + VerifyItem(2, valueTuple6.Item2, expectedValue[1]); + VerifyItem(3, valueTuple6.Item3, expectedValue[2]); + VerifyItem(4, valueTuple6.Item4, expectedValue[3]); + VerifyItem(5, valueTuple6.Item5, expectedValue[4]); + VerifyItem(6, valueTuple6.Item6, expectedValue[5]); + break; + case 7: + VerifyItem(1, valueTuple7.Item1, expectedValue[0]); + VerifyItem(2, valueTuple7.Item2, expectedValue[1]); + VerifyItem(3, valueTuple7.Item3, expectedValue[2]); + VerifyItem(4, valueTuple7.Item4, expectedValue[3]); + VerifyItem(5, valueTuple7.Item5, expectedValue[4]); + VerifyItem(6, valueTuple7.Item6, expectedValue[5]); + VerifyItem(7, valueTuple7.Item7, expectedValue[6]); + break; + case 8: // Extended ValueTuple + VerifyItem(1, valueTuple8.Item1, expectedValue[0]); + VerifyItem(2, valueTuple8.Item2, expectedValue[1]); + VerifyItem(3, valueTuple8.Item3, expectedValue[2]); + VerifyItem(4, valueTuple8.Item4, expectedValue[3]); + VerifyItem(5, valueTuple8.Item5, expectedValue[4]); + VerifyItem(6, valueTuple8.Item6, expectedValue[5]); + VerifyItem(7, valueTuple8.Item7, expectedValue[6]); + VerifyItem(8, valueTuple8.Rest.Item1, expectedValue[7]); + break; + case 9: // Extended ValueTuple + VerifyItem(1, valueTuple9.Item1, expectedValue[0]); + VerifyItem(2, valueTuple9.Item2, expectedValue[1]); + VerifyItem(3, valueTuple9.Item3, expectedValue[2]); + VerifyItem(4, valueTuple9.Item4, expectedValue[3]); + VerifyItem(5, valueTuple9.Item5, expectedValue[4]); + VerifyItem(6, valueTuple9.Item6, expectedValue[5]); + VerifyItem(7, valueTuple9.Item7, expectedValue[6]); + VerifyItem(8, valueTuple9.Rest.Item1, expectedValue[7]); + VerifyItem(9, valueTuple9.Rest.Item2, expectedValue[8]); + break; + case 10: // Extended ValueTuple + VerifyItem(1, valueTuple10.Item1, expectedValue[0]); + VerifyItem(2, valueTuple10.Item2, expectedValue[1]); + VerifyItem(3, valueTuple10.Item3, expectedValue[2]); + VerifyItem(4, valueTuple10.Item4, expectedValue[3]); + VerifyItem(5, valueTuple10.Item5, expectedValue[4]); + VerifyItem(6, valueTuple10.Item6, expectedValue[5]); + VerifyItem(7, valueTuple10.Item7, expectedValue[6]); + VerifyItem(8, valueTuple10.Rest.Item1, expectedValue[7]); + VerifyItem(9, valueTuple10.Rest.Item2, expectedValue[8]); + VerifyItem(10, valueTuple10.Rest.Item3, expectedValue[9]); + break; + default: + throw new ArgumentException("Must specify between 0 and 10 expected values (inclusive)."); + } + } + + public void TestToString(string expected) + { + Assert.Equal(expected, valueTuple.ToString()); + } + + public void TestEquals_GetHashCode(ValueTupleTestDriver other, bool expectEqual, bool expectStructuallyEqual) + { + if (expectEqual) + { + Assert.True(valueTuple.Equals(other.valueTuple)); + Assert.Equal(valueTuple.GetHashCode(), other.valueTuple.GetHashCode()); + } + else + { + Assert.False(valueTuple.Equals(other.valueTuple)); + Assert.NotEqual(valueTuple.GetHashCode(), other.valueTuple.GetHashCode()); + } + + if (expectStructuallyEqual) + { + var equatable = ((IStructuralEquatable)valueTuple); + var otherEquatable = ((IStructuralEquatable)other.valueTuple); + Assert.True(equatable.Equals(other.valueTuple, TestEqualityComparer.Instance)); + Assert.Equal(equatable.GetHashCode(TestEqualityComparer.Instance), otherEquatable.GetHashCode(TestEqualityComparer.Instance)); + } + else + { + var equatable = ((IStructuralEquatable)valueTuple); + var otherEquatable = ((IStructuralEquatable)other.valueTuple); + Assert.False(equatable.Equals(other.valueTuple, TestEqualityComparer.Instance)); + Assert.NotEqual(equatable.GetHashCode(TestEqualityComparer.Instance), otherEquatable.GetHashCode(TestEqualityComparer.Instance)); + } + + Assert.False(valueTuple.Equals(null)); + Assert.False(((IStructuralEquatable)valueTuple).Equals(null)); + IStructuralEquatable_Equals_NullComparer_ThrowsNullReferenceException(); + IStructuralEquatable_GetHashCode_NullComparer_ThrowsNullReferenceException(); + } + + public void IStructuralEquatable_Equals_NullComparer_ThrowsNullReferenceException() + { + // This was not fixed in order to be compatible with the full .NET framework and Xamarin. See #13429 + IStructuralEquatable equatable = (IStructuralEquatable)valueTuple; + if (valueTuple is ValueTuple) + { + Assert.True(equatable.Equals(valueTuple, null)); + } + else + { + Assert.Throws(() => equatable.Equals(valueTuple, null)); + } + } + + public void IStructuralEquatable_GetHashCode_NullComparer_ThrowsNullReferenceException() + { + // This was not fixed in order to be compatible with the full .NET framework and Xamarin. See #13429 + IStructuralEquatable equatable = (IStructuralEquatable)valueTuple; + if (valueTuple is ValueTuple) + { + Assert.Equal(0, valueTuple.GetHashCode()); + } + else + { + Assert.Throws(() => equatable.GetHashCode(null)); + } + } + + public void TestCompareTo(ValueTupleTestDriver other, int expectedResult, int expectedStructuralResult) + { + Assert.Equal(expectedResult, ((IComparable)valueTuple).CompareTo(other.valueTuple)); + Assert.Equal(expectedStructuralResult, ((IStructuralComparable)valueTuple).CompareTo(other.valueTuple, DummyTestComparer.Instance)); + Assert.Equal(1, ((IComparable)valueTuple).CompareTo(null)); + + IStructuralComparable_NullComparer_ThrowsNullReferenceException(); + } + + public void IStructuralComparable_NullComparer_ThrowsNullReferenceException() + { + // This was not fixed in order to be compatible with the full .NET framework and Xamarin. See #13429 + IStructuralComparable comparable = (IStructuralComparable)valueTuple; + if (valueTuple is ValueTuple) + { + Assert.Equal(0, comparable.CompareTo(valueTuple, null)); + } + else + { + Assert.Throws(() => comparable.CompareTo(valueTuple, null)); + } + } + + public void TestNotEqual() + { + ValueTuple ValueTupleB = new ValueTuple((int)10000); + Assert.NotEqual(valueTuple, ValueTupleB); + } + + internal void TestCompareToThrows() + { + ValueTuple ValueTupleB = new ValueTuple((int)10000); + AssertExtensions.Throws("other", () => ((IComparable)valueTuple).CompareTo(ValueTupleB)); + } + } + + [Fact] + public static void TestConstructor() + { + ValueTupleTestDriver, TimeSpan> ValueTupleDriverA; + //ValueTuple-0 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(); + ValueTupleDriverA.TestConstructor(); + + //ValueTuple-1 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(short.MaxValue); + ValueTupleDriverA.TestConstructor(short.MaxValue); + + //ValueTuple-2 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(short.MinValue, int.MaxValue); + ValueTupleDriverA.TestConstructor(short.MinValue, int.MaxValue); + + //ValueTuple-3 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, long.MaxValue); + ValueTupleDriverA.TestConstructor((short)0, (int)0, long.MaxValue); + + //ValueTuple-4 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "This"); + ValueTupleDriverA.TestConstructor((short)1, (int)1, long.MinValue, "This"); + + //ValueTuple-5 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), (long)0, "is", 'A'); + ValueTupleDriverA.TestConstructor((short)(-1), (int)(-1), (long)0, "is", 'A'); + + //ValueTuple-6 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MaxValue); + ValueTupleDriverA.TestConstructor((short)10, (int)100, (long)1, "testing", 'Z', Single.MaxValue); + + //ValueTuple-7 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue); + ValueTupleDriverA.TestConstructor((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue); + + object myObj = new object(); + //ValueTuple-10 + DateTime now = DateTime.Now; + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', (Single)0.0001, (Double)0.0000001, now, ValueTuple.Create(false, myObj), TimeSpan.Zero); + ValueTupleDriverA.TestConstructor((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', (Single)0.0001, (Double)0.0000001, now, ValueTuple.Create(false, myObj), TimeSpan.Zero); + } + + [Fact] + public static void TestToString() + { + ValueTupleTestDriver, TimeSpan> ValueTupleDriverA; + //ValueTuple-0 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(); + ValueTupleDriverA.TestToString("()"); + + //ValueTuple-1 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(short.MaxValue); + ValueTupleDriverA.TestToString("(" + short.MaxValue + ")"); + + //ValueTuple-2 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(short.MinValue, int.MaxValue); + ValueTupleDriverA.TestToString("(" + short.MinValue + ", " + int.MaxValue + ")"); + + //ValueTuple-3 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, long.MaxValue); + ValueTupleDriverA.TestToString("(" + ((short)0) + ", " + ((int)0) + ", " + long.MaxValue + ")"); + + //ValueTuple-4 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "This"); + ValueTupleDriverA.TestConstructor((short)1, (int)1, long.MinValue, "This"); + ValueTupleDriverA.TestToString("(" + ((short)1) + ", " + ((int)1) + ", " + long.MinValue + ", This)"); + + //ValueTuple-5 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), (long)0, "is", 'A'); + ValueTupleDriverA.TestToString("(" + ((short)(-1)) + ", " + ((int)(-1)) + ", " + ((long)0) + ", is, A)"); + + //ValueTuple-6 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MaxValue); + ValueTupleDriverA.TestToString("(" + ((short)10) + ", " + ((int)100) + ", " + ((long)1) + ", testing, Z, " + Single.MaxValue + ")"); + + //ValueTuple-7 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue); + ValueTupleDriverA.TestToString("(" + ((short)(-100)) + ", " + ((int)(-1000)) + ", " + ((long)(-1)) + ", ValueTuples, , " + Single.MinValue + ", " + Double.MaxValue + ")"); + + object myObj = new object(); + //ValueTuple-10 + DateTime now = DateTime.Now; + + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', (Single)0.0001, (Double)0.0000001, now, ValueTuple.Create(false, myObj), TimeSpan.Zero); + // .NET Native bug 438149 - object.ToString in incorrect + ValueTupleDriverA.TestToString("(" + ((short)10000) + ", " + ((int)1000000) + ", " + ((long)10000000) + ", 2008?7?2?, 0, " + ((Single)0.0001) + ", " + ((Double)0.0000001) + ", " + now + ", (False, System.Object), " + TimeSpan.Zero + ")"); + } + + [Fact] + public static void TestEquals_GetHashCode() + { + ValueTupleTestDriver, TimeSpan> ValueTupleDriverA, ValueTupleDriverB, ValueTupleDriverC, ValueTupleDriverD; + //ValueTuple-0 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>(); + ValueTupleDriverD = new ValueTupleTestDriver, TimeSpan>(short.MaxValue, int.MaxValue); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverD, false, false); + + //ValueTuple-1 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(short.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>(short.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>(short.MinValue); + ValueTupleDriverD = new ValueTupleTestDriver, TimeSpan>(short.MaxValue, int.MaxValue); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverD, false, false); + + //ValueTuple-2 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(short.MinValue, int.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>(short.MinValue, int.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>(short.MinValue, int.MinValue); + ValueTupleDriverD = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), long.MinValue); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverD, false, false); + + //ValueTuple-3 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, long.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, long.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), long.MinValue); + ValueTupleDriverD = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "this"); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverD, false, false); + + //ValueTuple-4 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "This"); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "This"); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "this"); + ValueTupleDriverD = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, (long)1, "IS", 'a'); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverD, false, false); + + //ValueTuple-5 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), (long)0, "is", 'A'); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), (long)0, "is", 'A'); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, (long)1, "IS", 'a'); + ValueTupleDriverD = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MinValue); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverD, false, false); + + //ValueTuple-6 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MinValue); + ValueTupleDriverD = new ValueTupleTestDriver, TimeSpan>((short)(-101), (int)(-1001), (long)(-2), "ValueTuples", ' ', Single.MinValue, (Double)0.0); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverD, false, false); + + //ValueTuple-7 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)(-101), (int)(-1001), (long)(-2), "ValueTuples", ' ', Single.MinValue, (Double)0.0); + ValueTupleDriverD = new ValueTupleTestDriver, TimeSpan>((short)10001, (int)1000001, (long)10000001, "2008?7?3?", '1', (Single)0.0002, (Double)0.0000002, DateTime.Now.AddMilliseconds(1)); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverD, false, false); + + //ValueTuple-8 + DateTime now = DateTime.Now; + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue, now); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue, now); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)(-101), (int)(-1001), (long)(-2), "ValueTuples", ' ', Single.MinValue, (Double)0.0, now.AddMilliseconds(1)); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + + object myObj = new object(); + //ValueTuple-10 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', (Single)0.0001, (Double)0.0000001, now, ValueTuple.Create(false, myObj), TimeSpan.Zero); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', (Single)0.0001, (Double)0.0000001, now, ValueTuple.Create(false, myObj), TimeSpan.Zero); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)10001, (int)1000001, (long)10000001, "2008?7?3?", '1', (Single)0.0002, (Double)0.0000002, now.AddMilliseconds(1), ValueTuple.Create(true, myObj), TimeSpan.MaxValue); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverB, true, true); + ValueTupleDriverA.TestEquals_GetHashCode(ValueTupleDriverC, false, false); + } + + [Fact] + public static void TestCompareTo() + { + ValueTupleTestDriver, TimeSpan> ValueTupleDriverA, ValueTupleDriverB, ValueTupleDriverC; + //ValueTuple-0 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>(); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 0); + + //ValueTuple-1 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(short.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>(short.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>(short.MinValue); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 5); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverC, 65535, 5); + //ValueTuple-2 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>(short.MinValue, int.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>(short.MinValue, int.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>(short.MinValue, int.MinValue); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 5); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverC, 1, 5); + //ValueTuple-3 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, long.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, long.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), long.MinValue); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 5); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverC, 1, 5); + //ValueTuple-4 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "This"); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "This"); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)1, (int)1, long.MinValue, "this"); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 5); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverC, 1, 5); + //ValueTuple-5 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), (long)0, "is", 'A'); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)(-1), (int)(-1), (long)0, "is", 'A'); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)0, (int)0, (long)1, "IS", 'a'); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 5); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverC, -1, 5); + //ValueTuple-6 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)10, (int)100, (long)1, "testing", 'Z', Single.MinValue); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 5); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverC, 1, 5); + //ValueTuple-7 + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)(-100), (int)(-1000), (long)(-1), "ValueTuples", ' ', Single.MinValue, Double.MaxValue); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)(-101), (int)(-1001), (long)(-2), "ValueTuples", ' ', Single.MinValue, (Double)0.0); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 5); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverC, 1, 5); + + object myObj = new object(); + //ValueTuple-10 + DateTime now = DateTime.Now; + + ValueTupleDriverA = new ValueTupleTestDriver, TimeSpan>((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', (Single)0.0001, (Double)0.0000001, now, ValueTuple.Create(false, myObj), TimeSpan.Zero); + ValueTupleDriverB = new ValueTupleTestDriver, TimeSpan>((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', (Single)0.0001, (Double)0.0000001, now, ValueTuple.Create(false, myObj), TimeSpan.Zero); + ValueTupleDriverC = new ValueTupleTestDriver, TimeSpan>((short)10001, (int)1000001, (long)10000001, "2008?7?3?", '1', (Single)0.0002, (Double)0.0000002, now.AddMilliseconds(1), ValueTuple.Create(true, myObj), TimeSpan.MaxValue); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverB, 0, 5); + ValueTupleDriverA.TestCompareTo(ValueTupleDriverC, -1, 5); + } + + [Fact] + public static void TestNotEqual() + { + ValueTupleTestDriver ValueTupleDriverA; + //ValueTuple-0 + ValueTupleDriverA = new ValueTupleTestDriver(); + ValueTupleDriverA.TestNotEqual(); + + //ValueTuple-1 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000); + ValueTupleDriverA.TestNotEqual(); + + // This is for code coverage purposes + //ValueTuple-2 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000); + ValueTupleDriverA.TestNotEqual(); + + //ValueTuple-3 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000); + ValueTupleDriverA.TestNotEqual(); + + //ValueTuple-4 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?"); + ValueTupleDriverA.TestNotEqual(); + + //ValueTuple-5 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0'); + ValueTupleDriverA.TestNotEqual(); + + //ValueTuple-6 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', Single.NaN); + ValueTupleDriverA.TestNotEqual(); + + //ValueTuple-7 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', Single.NaN, Double.NegativeInfinity); + ValueTupleDriverA.TestNotEqual(); + + //ValueTuple-8, extended ValueTuple + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', Single.NaN, Double.NegativeInfinity, DateTime.Now); + ValueTupleDriverA.TestNotEqual(); + + //ValueTuple-9 and ValueTuple-10 are not necessary because they use the same code path as ValueTuple-8 + } + + [Fact] + public static void IncomparableTypes() + { + ValueTupleTestDriver ValueTupleDriverA; + + //ValueTuple-0 + ValueTupleDriverA = new ValueTupleTestDriver(); + ValueTupleDriverA.TestCompareToThrows(); + + //ValueTuple-1 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000); + ValueTupleDriverA.TestCompareToThrows(); + + // This is for code coverage purposes + //ValueTuple-2 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000); + ValueTupleDriverA.TestCompareToThrows(); + + //ValueTuple-3 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000); + ValueTupleDriverA.TestCompareToThrows(); + + //ValueTuple-4 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?"); + ValueTupleDriverA.TestCompareToThrows(); + + //ValueTuple-5 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0'); + ValueTupleDriverA.TestCompareToThrows(); + + //ValueTuple-6 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', Single.NaN); + ValueTupleDriverA.TestCompareToThrows(); + + //ValueTuple-7 + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', Single.NaN, Double.NegativeInfinity); + ValueTupleDriverA.TestCompareToThrows(); + + //ValueTuple-8, extended ValueTuple + ValueTupleDriverA = new ValueTupleTestDriver((short)10000, (int)1000000, (long)10000000, "2008?7?2?", '0', Single.NaN, Double.NegativeInfinity, DateTime.Now); + ValueTupleDriverA.TestCompareToThrows(); + + //ValueTuple-9 and ValueTuple-10 are not necessary because they use the same code path as ValueTuple-8 + } + + [Fact] + public static void FloatingPointNaNCases() + { + var a = ValueTuple.Create(Double.MinValue, Double.NaN, Single.MinValue, Single.NaN); + var b = ValueTuple.Create(Double.MinValue, Double.NaN, Single.MinValue, Single.NaN); + + Assert.True(a.Equals(b)); + Assert.Equal(0, ((IComparable)a).CompareTo(b)); + Assert.Equal(a.GetHashCode(), b.GetHashCode()); + Assert.True(((IStructuralEquatable)a).Equals(b, TestEqualityComparer.Instance)); + Assert.Equal(5, ((IStructuralComparable)a).CompareTo(b, DummyTestComparer.Instance)); + Assert.Equal( + ((IStructuralEquatable)a).GetHashCode(TestEqualityComparer.Instance), + ((IStructuralEquatable)b).GetHashCode(TestEqualityComparer.Instance)); + } + + [Fact] + public static void TestCustomTypeParameter1() + { + // Special case of ValueTuple where T1 is a custom type + var testClass = new TestClass(); + var a = ValueTuple.Create(testClass); + var b = ValueTuple.Create(testClass); + + Assert.True(a.Equals(b)); + Assert.Equal(0, ((IComparable)a).CompareTo(b)); + Assert.Equal(a.GetHashCode(), b.GetHashCode()); + Assert.True(((IStructuralEquatable)a).Equals(b, TestEqualityComparer.Instance)); + Assert.Equal(5, ((IStructuralComparable)a).CompareTo(b, DummyTestComparer.Instance)); + Assert.Equal( + ((IStructuralEquatable)a).GetHashCode(TestEqualityComparer.Instance), + ((IStructuralEquatable)b).GetHashCode(TestEqualityComparer.Instance)); + } + + [Fact] + public static void TestCustomTypeParameter2() + { + // Special case of ValueTuple where T2 is a custom type + var testClass = new TestClass(1); + var a = ValueTuple.Create(1, testClass); + var b = ValueTuple.Create(1, testClass); + + Assert.True(a.Equals(b)); + Assert.Equal(0, ((IComparable)a).CompareTo(b)); + Assert.Equal(a.GetHashCode(), b.GetHashCode()); + Assert.True(((IStructuralEquatable)a).Equals(b, TestEqualityComparer.Instance)); + Assert.Equal(5, ((IStructuralComparable)a).CompareTo(b, DummyTestComparer.Instance)); + Assert.Equal( + ((IStructuralEquatable)a).GetHashCode(TestEqualityComparer.Instance), + ((IStructuralEquatable)b).GetHashCode(TestEqualityComparer.Instance)); + } + + [Fact] + public static void TestCustomTypeParameter3() + { + // Special case of ValueTuple where T1 and T2 are custom types + var testClassA = new TestClass(100); + var testClassB = new TestClass(101); + var a = ValueTuple.Create(testClassA, testClassB); + var b = ValueTuple.Create(testClassB, testClassA); + + Assert.False(a.Equals(b)); + Assert.Equal(-1, ((IComparable)a).CompareTo(b)); + Assert.False(((IStructuralEquatable)a).Equals(b, TestEqualityComparer.Instance)); + Assert.Equal(5, ((IStructuralComparable)a).CompareTo(b, DummyTestComparer.Instance)); + // Equals(IEqualityComparer) is false, ignore hash code + } + + [Fact] + public static void TestCustomTypeParameter4() + { + // Special case of ValueTuple where T1 and T2 are custom types + var testClassA = new TestClass(100); + var testClassB = new TestClass(101); + var a = ValueTuple.Create(testClassA, testClassB); + var b = ValueTuple.Create(testClassA, testClassA); + + Assert.False(a.Equals(b)); + Assert.Equal(1, ((IComparable)a).CompareTo(b)); + Assert.False(((IStructuralEquatable)a).Equals(b, TestEqualityComparer.Instance)); + Assert.Equal(5, ((IStructuralComparable)a).CompareTo(b, DummyTestComparer.Instance)); + // Equals(IEqualityComparer) is false, ignore hash code + } + + [Fact] + public static void NestedValueTuples1() + { + var a = ValueTuple.Create(1, 2, ValueTuple.Create(31, 32), 4, 5, 6, 7, ValueTuple.Create(8, 9)); + var b = ValueTuple.Create(1, 2, ValueTuple.Create(31, 32), 4, 5, 6, 7, ValueTuple.Create(8, 9)); + + Assert.True(a.Equals(b)); + Assert.Equal(0, ((IComparable)a).CompareTo(b)); + Assert.Equal(a.GetHashCode(), b.GetHashCode()); + Assert.True(((IStructuralEquatable)a).Equals(b, TestEqualityComparer.Instance)); + Assert.Equal(5, ((IStructuralComparable)a).CompareTo(b, DummyTestComparer.Instance)); + Assert.Equal( + ((IStructuralEquatable)a).GetHashCode(TestEqualityComparer.Instance), + ((IStructuralEquatable)b).GetHashCode(TestEqualityComparer.Instance)); + Assert.Equal("(1, 2, (31, 32), 4, 5, 6, 7, (8, 9))", a.ToString()); + Assert.Equal("(31, 32)", a.Item3.ToString()); + Assert.Equal("((8, 9))", a.Rest.ToString()); + } + + [Fact] + public static void NestedValueTuples2() + { + var a = ValueTuple.Create(0, 1, 2, 3, 4, 5, 6, ValueTuple.Create(7, 8, 9, 10, 11, 12, 13, ValueTuple.Create(14, 15))); + var b = ValueTuple.Create(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8, 9, 10, 11, 12, 13, 14, ValueTuple.Create(15, 16))); + + Assert.False(a.Equals(b)); + Assert.Equal(-1, ((IComparable)a).CompareTo(b)); + Assert.False(((IStructuralEquatable)a).Equals(b, TestEqualityComparer.Instance)); + Assert.Equal(5, ((IStructuralComparable)a).CompareTo(b, DummyTestComparer.Instance)); + + Assert.Equal("(0, 1, 2, 3, 4, 5, 6, (7, 8, 9, 10, 11, 12, 13, (14, 15)))", a.ToString()); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, (8, 9, 10, 11, 12, 13, 14, (15, 16)))", b.ToString()); + Assert.Equal("((7, 8, 9, 10, 11, 12, 13, (14, 15)))", a.Rest.ToString()); + + var a2 = Tuple.Create(0, 1, 2, 3, 4, 5, 6, Tuple.Create(7, 8, 9, 10, 11, 12, 13, Tuple.Create(14, 15))); + var b2 = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12, 13, 14, Tuple.Create(15, 16))); + + Assert.Equal(a2.ToString(), a.ToString()); + Assert.Equal(b2.ToString(), b.ToString()); + Assert.Equal(a2.Rest.ToString(), a.Rest.ToString()); + } + + [Fact] + public static void IncomparableTypesSpecialCase() + { + // Special case when T does not implement IComparable + var testClassA = new TestClass2(100); + var testClassB = new TestClass2(100); + var a = ValueTuple.Create(testClassA); + var b = ValueTuple.Create(testClassB); + + Assert.True(a.Equals(b)); + AssertExtensions.Throws(null, () => ((IComparable)a).CompareTo(b)); + Assert.Equal(a.GetHashCode(), b.GetHashCode()); + Assert.True(((IStructuralEquatable)a).Equals(b, TestEqualityComparer.Instance)); + Assert.Equal(5, ((IStructuralComparable)a).CompareTo(b, DummyTestComparer.Instance)); + Assert.Equal( + ((IStructuralEquatable)a).GetHashCode(TestEqualityComparer.Instance), + ((IStructuralEquatable)b).GetHashCode(TestEqualityComparer.Instance)); + Assert.Equal("([100])", a.ToString()); + } + + [Fact] + public static void ZeroTuples() + { + var a = ValueTuple.Create(); + Assert.True(a.Equals(new ValueTuple())); + Assert.Equal(0, a.CompareTo(new ValueTuple())); + + Assert.Equal(1, ((IStructuralComparable)a).CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => ((IStructuralComparable)a).CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, )", CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple()).ToString()); +#if netcoreapp + ITuple it = ValueTuple.Create(); + Assert.Throws(() => it[-1].ToString()); + Assert.Throws(() => it[0].ToString()); + Assert.Throws(() => it[1].ToString()); +#endif + } + + [Fact] + public static void OneTuples() + { + IComparable c = ValueTuple.Create(1); + + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(3))); + + IStructuralComparable sc = (IStructuralComparable)c; + + Assert.Equal(1, sc.CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => ((IStructuralComparable)sc).CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(3), TestComparer.Instance)); + + Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1)).ToString()); + + var vtWithNull = new ValueTuple(null); + var tupleWithNull = new Tuple(null); + Assert.Equal("()", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + +#if netcoreapp + ITuple it = ValueTuple.Create(1); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Throws(() => it[1].ToString()); +#endif + } + + [Fact] + public static void TwoTuples() + { + IComparable c = ValueTuple.Create(1, 1); + + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(3, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 3))); + + IStructuralComparable sc = (IStructuralComparable)c; + + Assert.Equal(1, sc.CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => ((IStructuralComparable)sc).CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 3), TestComparer.Instance)); + + Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2)).ToString()); + + var vtWithNull = new ValueTuple(null, null); + var tupleWithNull = new Tuple(null, null); + Assert.Equal("(, )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + +#if netcoreapp + ITuple it = ValueTuple.Create(1, 2); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Throws(() => it[2].ToString()); +#endif + } + + [Fact] + public static void ThreeTuples() + { + IComparable c = ValueTuple.Create(1, 1, 1); + + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(3, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 3, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 3))); + + IStructuralComparable sc = (IStructuralComparable)c; + + Assert.Equal(1, sc.CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => ((IStructuralComparable)sc).CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 3, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 3), TestComparer.Instance)); + + Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3)).ToString()); + + var vtWithNull = new ValueTuple(null, null, null); + var tupleWithNull = new Tuple(null, null, null); + Assert.Equal("(, , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + +#if netcoreapp + ITuple it = ValueTuple.Create(1, 2, 3); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Throws(() => it[3].ToString()); +#endif + } + + [Fact] + public static void FourTuples() + { + IComparable c = ValueTuple.Create(1, 1, 1, 1); + + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(3, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 3, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 3, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 3))); + + IStructuralComparable sc = (IStructuralComparable)c; + + Assert.Equal(1, sc.CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => ((IStructuralComparable)sc).CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(3, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 3, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 3, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 3), TestComparer.Instance)); + + Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3, 4)).ToString()); + + var vtWithNull = new ValueTuple(null, null, null, null); + var tupleWithNull = new Tuple(null, null, null, null); + Assert.Equal("(, , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + +#if netcoreapp + ITuple it = ValueTuple.Create(1, 2, 3, 4); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Throws(() => it[4].ToString()); +#endif + } + + [Fact] + public static void FiveTuples() + { + IComparable c = ValueTuple.Create(1, 1, 1, 1, 1); + + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(3, 1, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 3, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 3, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 3, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 1, 3))); + + IStructuralComparable sc = (IStructuralComparable)c; + + Assert.Equal(1, sc.CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => ((IStructuralComparable)sc).CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(3, 1, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 3, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 3, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 3, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 1, 3), TestComparer.Instance)); + + Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3, 4, 5)).ToString()); + + var vtWithNull = new ValueTuple(null, null, null, null, null); + var tupleWithNull = new Tuple(null, null, null, null, null); + Assert.Equal("(, , , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + +#if netcoreapp + ITuple it = ValueTuple.Create(1, 2, 3, 4, 5); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Equal(5, it[4]); + Assert.Throws(() => it[5].ToString()); +#endif + } + + [Fact] + public static void SixTuples() + { + IComparable c = ValueTuple.Create(1, 1, 1, 1, 1, 1); + + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(3, 1, 1, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 3, 1, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 3, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 3, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 1, 3, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 1, 1, 3))); + + IStructuralComparable sc = (IStructuralComparable)c; + + Assert.Equal(1, sc.CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => ((IStructuralComparable)sc).CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(3, 1, 1, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 3, 1, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 3, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 3, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 1, 3, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 1, 1, 3), TestComparer.Instance)); + + Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3, 4, 5, 6)).ToString()); + + var vtWithNull = new ValueTuple(null, null, null, null, null, null); + var tupleWithNull = new Tuple(null, null, null, null, null, null); + Assert.Equal("(, , , , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + +#if netcoreapp + ITuple it = ValueTuple.Create(1, 2, 3, 4, 5, 6); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Equal(5, it[4]); + Assert.Equal(6, it[5]); + Assert.Throws(() => it[6].ToString()); +#endif + } + + [Fact] + public static void SevenTuples() + { + IComparable c = ValueTuple.Create(1, 1, 1, 1, 1, 1, 1); + + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(3, 1, 1, 1, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 3, 1, 1, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 3, 1, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 3, 1, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 1, 3, 1, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 1, 1, 3, 1))); + Assert.Equal(-1, c.CompareTo(ValueTuple.Create(1, 1, 1, 1, 1, 1, 3))); + + IStructuralComparable sc = (IStructuralComparable)c; + + Assert.Equal(1, sc.CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => ((IStructuralComparable)sc).CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(3, 1, 1, 1, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 3, 1, 1, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 3, 1, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 3, 1, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 1, 3, 1, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 1, 1, 3, 1), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(ValueTuple.Create(1, 1, 1, 1, 1, 1, 3), TestComparer.Instance)); + + Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).ToString()); + + var vtWithNull = new ValueTuple(null, null, null, null, null, null, null); + var tupleWithNull = new Tuple(null, null, null, null, null, null, null); + Assert.Equal("(, , , , , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + +#if netcoreapp + ITuple it = ValueTuple.Create(1, 2, 3, 4, 5, 6, 7); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Equal(5, it[4]); + Assert.Equal(6, it[5]); + Assert.Equal(7, it[6]); + Assert.Throws(() => it[7].ToString()); +#endif + } + + public static ValueTuple CreateLong(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct + { + return new ValueTuple(item1, item2, item3, item4, item5, item6, item7, rest); + } + + public static Tuple CreateLongRef(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) + { + return new Tuple(item1, item2, item3, item4, item5, item6, item7, rest); + } + + [Fact] + public static void EightTuples() + { + var x = new Tuple>(1, 2, 3, 4, 5, 6, 7, new Tuple("alice", "bob")); + var y = new ValueTuple>(1, 2, 3, 4, 5, 6, 7, new ValueTuple("alice", "bob")); + Assert.Equal(x.ToString(), y.ToString()); + + var t = CreateLong(1, 1, 1, 1, 1, 1, 1, ValueTuple.Create(1)); + + IStructuralEquatable se = t; + Assert.False(se.Equals(null, TestEqualityComparer.Instance)); + Assert.False(se.Equals("string", TestEqualityComparer.Instance)); + Assert.False(se.Equals(new ValueTuple(), TestEqualityComparer.Instance)); + + IComparable c = t; + Assert.Equal(-1, c.CompareTo(CreateLong(3, 1, 1, 1, 1, 1, 1, ValueTuple.Create(1)))); + Assert.Equal(-1, c.CompareTo(CreateLong(1, 3, 1, 1, 1, 1, 1, ValueTuple.Create(1)))); + Assert.Equal(-1, c.CompareTo(CreateLong(1, 1, 3, 1, 1, 1, 1, ValueTuple.Create(1)))); + Assert.Equal(-1, c.CompareTo(CreateLong(1, 1, 1, 3, 1, 1, 1, ValueTuple.Create(1)))); + Assert.Equal(-1, c.CompareTo(CreateLong(1, 1, 1, 1, 3, 1, 1, ValueTuple.Create(1)))); + Assert.Equal(-1, c.CompareTo(CreateLong(1, 1, 1, 1, 1, 3, 1, ValueTuple.Create(1)))); + Assert.Equal(-1, c.CompareTo(CreateLong(1, 1, 1, 1, 1, 1, 3, ValueTuple.Create(1)))); + + IStructuralComparable sc = t; + Assert.Equal(1, sc.CompareTo(null, DummyTestComparer.Instance)); + AssertExtensions.Throws("other", () => sc.CompareTo("string", DummyTestComparer.Instance)); + + Assert.Equal(1, sc.CompareTo(CreateLong(3, 1, 1, 1, 1, 1, 1, ValueTuple.Create(1)), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(CreateLong(1, 3, 1, 1, 1, 1, 1, ValueTuple.Create(1)), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(CreateLong(1, 1, 3, 1, 1, 1, 1, ValueTuple.Create(1)), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(CreateLong(1, 1, 1, 3, 1, 1, 1, ValueTuple.Create(1)), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(CreateLong(1, 1, 1, 1, 3, 1, 1, ValueTuple.Create(1)), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(CreateLong(1, 1, 1, 1, 1, 3, 1, ValueTuple.Create(1)), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(CreateLong(1, 1, 1, 1, 1, 1, 3, ValueTuple.Create(1)), TestComparer.Instance)); + Assert.Equal(1, sc.CompareTo(CreateLong(1, 1, 1, 1, 1, 1, 1, ValueTuple.Create(3)), TestComparer.Instance)); + + Assert.False(se.Equals(t, DummyTestEqualityComparer.Instance)); + + // Notice that 0-tuple prints as empty position + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, )", CreateLong(1, 2, 3, 4, 5, 6, 7, CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create())).ToString()); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, 1)", CreateLong(1, 2, 3, 4, 5, 6, 7, CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1))).ToString()); + + var vtWithNull = new ValueTuple>(null, null, null, null, null, null, null, new ValueTuple(null)); + var tupleWithNull = new Tuple>(null, null, null, null, null, null, null, new Tuple(null)); + Assert.Equal("(, , , , , , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + +#if netcoreapp + ITuple it = CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)); + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(2, it[1]); + Assert.Equal(3, it[2]); + Assert.Equal(4, it[3]); + Assert.Equal(5, it[4]); + Assert.Equal(6, it[5]); + Assert.Equal(7, it[6]); + Assert.Equal(8, it[7]); + Assert.Throws(() => it[8].ToString()); +#endif + } + + [Fact] + public static void LongTuplesWithNull() + { + { + var vtWithNull = CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple(null)); + var tupleWithNull = CreateLongRef(1, 2, 3, 4, 5, 6, 7, new Tuple(null)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + } + + { + var vtWithNull = CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple(null)); + var tupleWithNull = CreateLongRef(1, 2, 3, 4, 5, 6, 7, new Tuple(null)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + } + + { + var vtWithNull = CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple(null, null)); + var tupleWithNull = CreateLongRef(1, 2, 3, 4, 5, 6, 7, new Tuple(null, null)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + } + + { + var vtWithNull = CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple(null, null, null)); + var tupleWithNull = CreateLongRef(1, 2, 3, 4, 5, 6, 7, new Tuple(null, null, null)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + } + + { + var vtWithNull = CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple(null, null, null, null)); + var tupleWithNull = CreateLongRef(1, 2, 3, 4, 5, 6, 7, new Tuple(null, null, null, null)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, , , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + } + + { + var vtWithNull = CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple(null, null, null, null, null)); + var tupleWithNull = CreateLongRef(1, 2, 3, 4, 5, 6, 7, new Tuple(null, null, null, null, null)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, , , , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + } + + { + var vtWithNull = CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple(null, null, null, null, null, null)); + var tupleWithNull = CreateLongRef(1, 2, 3, 4, 5, 6, 7, new Tuple(null, null, null, null, null, null)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, , , , , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + } + + { + var vtWithNull = CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple(null, null, null, null, null, null, null)); + var tupleWithNull = CreateLongRef(1, 2, 3, 4, 5, 6, 7, new Tuple(null, null, null, null, null, null, null)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, , , , , , , )", vtWithNull.ToString()); + Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); + } + } + + [Fact] + public static void EightTuplesWithBadRest() + { + var d = default(ValueTuple); + d.Item1 = 1; + d.Rest = 42; + Assert.Equal("(1, 0, 0, 0, 0, 0, 0, 42)", d.ToString()); + + // GetHashCode only tries to hash the first 7 elements when rest is not ITupleInternal + Assert.Equal(ValueTuple.Create(1, 0, 0, 0, 0, 0, 0).GetHashCode(), d.GetHashCode()); + Assert.Equal(((IStructuralEquatable)ValueTuple.Create(1, 0, 0, 0, 0, 0, 0)).GetHashCode(TestEqualityComparer.Instance), ((IStructuralEquatable)d).GetHashCode(TestEqualityComparer.Instance)); + + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 0, 0, 0, 0, 0, 0, 42)", CreateLong(1, 2, 3, 4, 5, 6, 7, d).ToString()); + +#if netcoreapp + ITuple it = d; + Assert.Throws(() => it[-1].ToString()); + Assert.Equal(1, it[0]); + Assert.Equal(0, it[1]); + Assert.Equal(0, it[2]); + Assert.Equal(0, it[3]); + Assert.Equal(0, it[4]); + Assert.Equal(0, it[5]); + Assert.Equal(0, it[6]); + Assert.Equal(42, it[7]); + Assert.Throws(() => it[8].ToString()); +#endif + } + +#if netcoreapp + [Fact] + public static void ValueTupleSerialization() + { + VerifySerialization(new ValueTuple()); + VerifySerialization(ValueTuple.Create(1)); + VerifySerialization(ValueTuple.Create(1, 2)); + VerifySerialization(ValueTuple.Create(1, 2, 3)); + VerifySerialization(ValueTuple.Create(1, 2, 3, 4)); + VerifySerialization(ValueTuple.Create(1, 2, 3, 4, 5)); + VerifySerialization(ValueTuple.Create(1, 2, 3, 4, 5, 6)); + VerifySerialization(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)); + VerifySerialization(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))); + } + + private static void VerifySerialization(T tuple) + { + T clone = BinaryFormatterHelpers.Clone(tuple); + Assert.Equal(tuple, clone); + } +#endif + + private class TestClass : IComparable + { + private readonly int _value; + + internal TestClass() + : this(0) + { } + + internal TestClass(int value) + { + this._value = value; + } + + public override string ToString() + { + return "{" + _value.ToString() + "}"; + } + + public int CompareTo(object x) + { + TestClass tmp = x as TestClass; + if (tmp != null) + return this._value.CompareTo(tmp._value); + else + return 1; + } + } + + private class TestClass2 + { + private readonly int _value; + + internal TestClass2() + : this(0) + { } + + internal TestClass2(int value) + { + this._value = value; + } + + public override string ToString() + { + return "[" + _value.ToString() + "]"; + } + + public override bool Equals(object x) + { + TestClass2 tmp = x as TestClass2; + if (tmp != null) + return _value.Equals(tmp._value); + else + return false; + } + + public override int GetHashCode() + { + return _value.GetHashCode(); + } + } + + private class DummyTestComparer : IComparer + { + public static readonly DummyTestComparer Instance = new DummyTestComparer(); + + public int Compare(object x, object y) + { + return 5; + } + } + + private class TestComparer : IComparer + { + public static readonly TestComparer Instance = new TestComparer(); + + public int Compare(object x, object y) + { + return x.Equals(y) ? 0 : 1; + } + } + + private class DummyTestEqualityComparer : IEqualityComparer + { + public static readonly DummyTestEqualityComparer Instance = new DummyTestEqualityComparer(); + + public new bool Equals(object x, object y) + { + return false; + } + + public int GetHashCode(object x) + { + return x.GetHashCode(); + } + } + + private class TestEqualityComparer : IEqualityComparer + { + public static readonly TestEqualityComparer Instance = new TestEqualityComparer(); + + public new bool Equals(object x, object y) + { + return x.Equals(y); + } + + public int GetHashCode(object x) + { + return x.GetHashCode(); + } + } + } +}