Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Using ITuple as constraint on TRest
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv committed Jul 14, 2016
1 parent 176a739 commit 669260f
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13
}
#endregion

private static ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLong<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct =>
private static ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLong<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct, ITuple =>
new ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest);

private static Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLongRef<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) =>
Expand Down
51 changes: 21 additions & 30 deletions src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,12 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length => 0;
int ITuple.Length => 0;

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand Down Expand Up @@ -451,12 +451,12 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length => 1;
int ITuple.Length => 1;

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand Down Expand Up @@ -654,12 +654,12 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length => 2;
int ITuple.Length => 2;

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand Down Expand Up @@ -857,12 +857,12 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length => 3;
int ITuple.Length => 3;

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand Down Expand Up @@ -1079,12 +1079,12 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length => 4;
int ITuple.Length => 4;

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand Down Expand Up @@ -1320,12 +1320,12 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length => 5;
int ITuple.Length => 5;

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand Down Expand Up @@ -1580,12 +1580,12 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length => 6;
int ITuple.Length => 6;

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand Down Expand Up @@ -1859,12 +1859,12 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length => 7;
int ITuple.Length => 7;

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand Down Expand Up @@ -1904,7 +1904,7 @@ public object this[int index]
/// <typeparam name="TRest">The type of the tuple's eigth component.</typeparam>
public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>
: IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, ITupleInternal, ITuple
where TRest : struct
where TRest : struct, ITuple
{
/// <summary>
/// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's first component.
Expand Down Expand Up @@ -2272,19 +2272,18 @@ string ITupleInternal.ToStringEnd()
/// <summary>
/// The number of positions in this data structure.
/// </summary>
public int Length
int ITuple.Length
{
get
{
ITupleInternal rest = Rest as ITupleInternal;
return rest == null ? 8 : 7 + rest.Length;
return 7 + ((ITuple)Rest).Length;
}
}

/// <summary>
/// Get the element at position <param name="index"/>.
/// </summary>
public object this[int index]
object ITuple.this[int index]
{
get
{
Expand All @@ -2306,15 +2305,7 @@ public object this[int index]
return Item7;
}

ITupleInternal rest = Rest as ITupleInternal;
if (index > 0 && index < Length && rest != null)
{
return rest[index - 7];
}
else
{
throw new IndexOutOfRangeException();
}
return ((ITuple)Rest)[index - 7];
}
}
}
Expand Down
39 changes: 33 additions & 6 deletions src/System.ValueTuple/tests/ValueTuple/UnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ public static void SevenTuples()
Assert.Throws<IndexOutOfRangeException>(() => it[7]);
}

public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLong<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct =>
public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLong<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct, ITuple =>
new ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest);

public static Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLongRef<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) =>
Expand Down Expand Up @@ -1147,20 +1147,19 @@ public static void LongTuplesWithNull()
[Fact]
public static void EightTuplesWithBadRest()
{
var d = default(ValueTuple<int, int, int, int, int, int, int, int>);
var d = default(ValueTuple<int, int, int, int, int, int, int, BadTuple>);
d.Item1 = 1;
d.Rest = 42;
Assert.Equal(35937, d.GetHashCode());
Assert.Equal(35937, ((IStructuralEquatable)d).GetHashCode());
Assert.Equal("(1, 0, 0, 0, 0, 0, 0, 42)", d.ToString());
Assert.Equal("(1, 0, 0, 0, 0, 0, 0, BadTuple)", d.ToString());

Assert.Equal(35937, CreateLong(1, 2, 3, 4, 5, 6, 7, d).GetHashCode());

// 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());
Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 0, 0, 0, 0, 0, 0, BadTuple)", CreateLong(1, 2, 3, 4, 5, 6, 7, d).ToString());

ITuple it = d;
Assert.Throws<IndexOutOfRangeException>(() => it[-1]);
Expand All @@ -1171,7 +1170,35 @@ public static void EightTuplesWithBadRest()
Assert.Equal(0, it[4]);
Assert.Equal(0, it[5]);
Assert.Equal(0, it[6]);
Assert.Throws<IndexOutOfRangeException>(() => it[7]);
Assert.Equal(42, it[7]);
Assert.Throws<IndexOutOfRangeException>(() => it[8]);
}

private struct BadTuple : ITuple
{
// doesn't implement ITupleInternal

int ITuple.Length => 1;

object ITuple.this[int index]
{
get
{
if (index == 0)
{
return 42;
}
else
{
throw new IndexOutOfRangeException();
}
}
}

public override string ToString()
{
return "BadTuple";
}
}

private class TestClass : IComparable
Expand Down

0 comments on commit 669260f

Please sign in to comment.