summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Warren <matt.warren@live.co.uk>2016-11-30 07:45:21 +0000
committerJan Kotas <jkotas@microsoft.com>2016-11-29 23:45:21 -0800
commitfb5f8d70e8b85e084af2cb52b70914b3428652a1 (patch)
tree66fc375909ba2fed7ce93a23241170155a9c2f62
parentce9a231f1498719eb665e2017611d7bfeb41ed49 (diff)
downloadcoreclr-fb5f8d70e8b85e084af2cb52b70914b3428652a1.tar.gz
coreclr-fb5f8d70e8b85e084af2cb52b70914b3428652a1.tar.bz2
coreclr-fb5f8d70e8b85e084af2cb52b70914b3428652a1.zip
Adding missing ctor - 'public Span(T[] array, int start)' (#8354)
-rw-r--r--src/mscorlib/model.xml2
-rw-r--r--src/mscorlib/src/System/ReadOnlySpan.cs25
-rw-r--r--src/mscorlib/src/System/Span.cs30
-rw-r--r--tests/src/CoreMangLib/system/span/BasicSpanTest.cs129
4 files changed, 179 insertions, 7 deletions
diff --git a/src/mscorlib/model.xml b/src/mscorlib/model.xml
index 71c8cab22e..c338e5c0ef 100644
--- a/src/mscorlib/model.xml
+++ b/src/mscorlib/model.xml
@@ -12397,6 +12397,7 @@
</Type>
<Type Name="System.Span&lt;T&gt;" Condition="FEATURE_SPAN_OF_T">
<Member Name="#ctor(T[])" />
+ <Member Name="#ctor(T[],System.Int32)" />
<Member Name="#ctor(T[],System.Int32,System.Int32)" />
<Member Name="#ctor(System.Void*,System.Int32)" />
<Member Name="op_Implicit(T[])" ReturnType="System.Span&lt;T&gt;" />
@@ -12415,6 +12416,7 @@
</Type>
<Type Name="System.ReadOnlySpan&lt;T&gt;" Condition="FEATURE_SPAN_OF_T">
<Member Name="#ctor(T[])" />
+ <Member Name="#ctor(T[],System.Int32)" />
<Member Name="#ctor(T[],System.Int32,System.Int32)" />
<Member Name="#ctor(System.Void*,System.Int32)" />
<Member Name="op_Implicit(System.Span&lt;T&gt;)" ReturnType="System.ReadOnlySpan&lt;T&gt;" />
diff --git a/src/mscorlib/src/System/ReadOnlySpan.cs b/src/mscorlib/src/System/ReadOnlySpan.cs
index 4cdd14dfe4..e94d3534fc 100644
--- a/src/mscorlib/src/System/ReadOnlySpan.cs
+++ b/src/mscorlib/src/System/ReadOnlySpan.cs
@@ -38,6 +38,29 @@ namespace System
/// <summary>
/// Creates a new span over the portion of the target array beginning
+ /// at 'start' index and covering the remainder of the array.
+ /// </summary>
+ /// <param name="array">The target array.</param>
+ /// <param name="start">The index at which to begin the span.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> is not in the range (&lt;0 or &gt;&eq;Length).
+ /// </exception>
+ public ReadOnlySpan(T[] array, int start)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if ((uint)start > (uint)array.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ // TODO-SPAN: This has GC hole. It needs to be JIT intrinsic instead
+ _rawPointer = (IntPtr)Unsafe.AsPointer(ref Unsafe.Add(ref JitHelpers.GetArrayData(array), start));
+ _length = array.Length - start;
+ }
+
+ /// <summary>
+ /// Creates a new span over the portion of the target array beginning
/// at 'start' index and ending at 'end' index (exclusive).
/// </summary>
/// <param name="array">The target array.</param>
@@ -46,7 +69,7 @@ namespace System
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
/// reference (Nothing in Visual Basic).</exception>
/// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="start"/> or end index is not in range (&lt;0 or &gt;&eq;Length).
+ /// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;&eq;Length).
/// </exception>
public ReadOnlySpan(T[] array, int start, int length)
{
diff --git a/src/mscorlib/src/System/Span.cs b/src/mscorlib/src/System/Span.cs
index 64764ed2fd..2eff6ae800 100644
--- a/src/mscorlib/src/System/Span.cs
+++ b/src/mscorlib/src/System/Span.cs
@@ -43,6 +43,34 @@ namespace System
/// <summary>
/// Creates a new span over the portion of the target array beginning
+ /// at 'start' index and covering the remainder of the array.
+ /// </summary>
+ /// <param name="array">The target array.</param>
+ /// <param name="start">The index at which to begin the span.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant.</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> is not in the range (&lt;0 or &gt;=Length).
+ /// </exception>
+ public Span(T[] array, int start)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if (default(T) == null) { // Arrays of valuetypes are never covariant
+ if (array.GetType() != typeof(T[]))
+ ThrowHelper.ThrowArrayTypeMismatchException();
+ }
+ if ((uint)start > (uint)array.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ // TODO-SPAN: This has GC hole. It needs to be JIT intrinsic instead
+ _rawPointer = (IntPtr)Unsafe.AsPointer(ref Unsafe.Add(ref JitHelpers.GetArrayData(array), start));
+ _length = array.Length - start;
+ }
+
+ /// <summary>
+ /// Creates a new span over the portion of the target array beginning
/// at 'start' index and ending at 'end' index (exclusive).
/// </summary>
/// <param name="array">The target array.</param>
@@ -52,7 +80,7 @@ namespace System
/// reference (Nothing in Visual Basic).</exception>
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant.</exception>
/// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="start"/> or end index is not in range (&lt;0 or &gt;&eq;Length).
+ /// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
/// </exception>
public Span(T[] array, int start, int length)
{
diff --git a/tests/src/CoreMangLib/system/span/BasicSpanTest.cs b/tests/src/CoreMangLib/system/span/BasicSpanTest.cs
index 7b0be909c7..18ec6f8474 100644
--- a/tests/src/CoreMangLib/system/span/BasicSpanTest.cs
+++ b/tests/src/CoreMangLib/system/span/BasicSpanTest.cs
@@ -41,8 +41,11 @@ class My
int failedTestsCount = 0;
Test(CanAccessItemsViaIndexer, "CanAccessItemsViaIndexer", ref failedTestsCount);
+ Test(CanAccessItemsViaIndexerStartCtor, "CanAccessItemsViaIndexerStartCtor", ref failedTestsCount);
+ Test(CanAccessItemsViaIndexerStartLengthCtor, "CanAccessItemsViaIndexerStartLengthCtor", ref failedTestsCount);
- Test(TestBoundaryEmptySpan, "TestBoundaryEmptySpan", ref failedTestsCount);
+ Test(TestBoundaryEmptySpanStartCtor, "TestBoundaryEmptySpanStartCtor", ref failedTestsCount);
+ Test(TestBoundaryEmptySpanStartLengthCtor, "TestBoundaryEmptySpanStartLengthCtor", ref failedTestsCount);
Test(ReferenceTypesAreSupported, "ReferenceTypesAreSupported", ref failedTestsCount);
@@ -51,6 +54,9 @@ class My
Test(MustNotMoveGcTypesToUnmanagedMemory, "MustNotMoveGcTypesToUnmanagedMemory", ref failedTestsCount);
Test(TestArrayCoVariance, "TestArrayCoVariance", ref failedTestsCount);
+ Test(TestArrayCoVarianceStartCtor, "TestArrayCoVarianceStartCtor", ref failedTestsCount);
+ Test(TestArrayCoVarianceStartLengthCtor, "TestArrayCoVarianceStartLengthCtor", ref failedTestsCount);
+
Test(TestArrayCoVarianceReadOnly, "TestArrayCoVarianceReadOnly", ref failedTestsCount);
Test(CanCopyValueTypesWithoutPointersToSlice, "CanCopyValueTypesWithoutPointersToSlice", ref failedTestsCount);
@@ -74,9 +80,13 @@ class My
Test(SourceTypeLargerThanTargetOneCorrectlyCalcsTargetsLength, "SourceTypeLargerThanTargetOneCorrectlyCalcsTargetsLength", ref failedTestsCount);
Test(WhenSourceDoesntFitIntoTargetLengthIsZero, "WhenSourceDoesntFitIntoTargetLengthIsZero", ref failedTestsCount);
Test(WhenSourceFitsIntoTargetOnceLengthIsOne, "WhenSourceFitsIntoTargetOnceLengthIsOne", ref failedTestsCount);
- Test(WhenSourceTypeLargerThaTargetAndOverflowsInt32ThrowsException, "WhenSourceTypeLargerThaTargetAndOverflowsInt32ThrowsException", ref failedTestsCount);
+ Test(WhenSourceTypeLargerThanTargetAndOverflowsInt32ThrowsException, "WhenSourceTypeLargerThanTargetAndOverflowsInt32ThrowsException", ref failedTestsCount);
Test(CanCreateSpanFromString, "CanCreateSpanFromString", ref failedTestsCount);
+ Test(WhenStartLargerThanLengthThrowsExceptionStartCtor, "WhenStartLargerThanLengthThrowsExceptionStartCtor", ref failedTestsCount);
+ Test(WhenStartLargerThanLengthThrowsExceptionStartLengthCtor, "WhenStartLargerThanLengthThrowsExceptionStartLengthCtor", ref failedTestsCount);
+ Test(WhenStartAndLengthLargerThanLengthThrowsExceptionStartLengthCtor, "WhenStartAndLengthLargerThanLengthThrowsExceptionStartLengthCtor", ref failedTestsCount);
+
Console.WriteLine(string.Format("{0} tests has failed", failedTestsCount));
Environment.Exit(failedTestsCount);
}
@@ -91,9 +101,31 @@ class My
AssertTrue(Sum(subslice) == 5, "Failed to sum subslice");
}
- static TestBoundaryEmptySpan()
+ static void CanAccessItemsViaIndexerStartCtor()
+ {
+ int[] a = new int[] { 1, 2, 3 };
+ Span<int> slice = new Span<int>(a, start: 1);
+ AssertTrue(Sum(slice) == 5, "Failed to sum slice");
+ }
+
+ static void CanAccessItemsViaIndexerStartLengthCtor()
+ {
+ int[] a = new int[] { 1, 2, 3 };
+ Span<int> slice = new Span<int>(a, start: 1, length: 1);
+ AssertTrue(Sum(slice) == 2, "Failed to sum slice");
+ }
+
+ static void TestBoundaryEmptySpanStartCtor()
{
- int[] a = new byte[5];
+ int[] a = new int[5];
+
+ Span<int> slice = new Span<int>(a, start: a.Length);
+ AssertEqual(slice.Length, 0);
+ }
+
+ static void TestBoundaryEmptySpanStartLengthCtor()
+ {
+ int[] a = new int[5];
Span<int> slice = new Span<int>(a, a.Length, 0);
AssertEqual(slice.Length, 0);
@@ -165,6 +197,54 @@ class My
}
}
+ static void TestArrayCoVarianceStartCtor()
+ {
+ var array = new ReferenceType[1];
+ var objArray = (object[])array;
+ try
+ {
+ new Span<object>(objArray, start: 0);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+
+ var objEmptyArray = Array.Empty<ReferenceType>();
+ try
+ {
+ new Span<object>(objEmptyArray, start: 0);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+ }
+
+ static void TestArrayCoVarianceStartLengthCtor()
+ {
+ var array = new ReferenceType[1];
+ var objArray = (object[])array;
+ try
+ {
+ new Span<object>(objArray, start: 0, length: 1);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+
+ var objEmptyArray = Array.Empty<ReferenceType>();
+ try
+ {
+ new Span<object>(objEmptyArray, start: 0, length: 1);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+ }
+
static void TestArrayCoVarianceReadOnly()
{
var array = new ReferenceType[1];
@@ -603,7 +683,7 @@ class My
}
}
- static void WhenSourceTypeLargerThaTargetAndOverflowsInt32ThrowsException()
+ static void WhenSourceTypeLargerThanTargetAndOverflowsInt32ThrowsException()
{
unsafe
{
@@ -637,6 +717,45 @@ class My
AssertEqualContent(secondHalfOfString, spanFromSecondHalf);
}
+ static void WhenStartLargerThanLengthThrowsExceptionStartCtor()
+ {
+ try
+ {
+ var data = new byte[10];
+ var slice = new Span<byte>(data, start: 11);
+ AssertTrue(false, "Expected exception for Argument Out of Range not thrown");
+ }
+ catch (System.ArgumentOutOfRangeException)
+ {
+ }
+ }
+
+ static void WhenStartLargerThanLengthThrowsExceptionStartLengthCtor()
+ {
+ try
+ {
+ var data = new byte[10];
+ var slice = new Span<byte>(data, start: 11, length: 0);
+ AssertTrue(false, "Expected exception for Argument Out of Range not thrown");
+ }
+ catch (System.ArgumentOutOfRangeException)
+ {
+ }
+ }
+
+ static void WhenStartAndLengthLargerThanLengthThrowsExceptionStartLengthCtor()
+ {
+ try
+ {
+ var data = new byte[10];
+ var slice = new Span<byte>(data, start: 1, length: 10);
+ AssertTrue(false, "Expected exception for Argument Out of Range not thrown");
+ }
+ catch (System.ArgumentOutOfRangeException)
+ {
+ }
+ }
+
static void Test(Action test, string testName, ref int failedTestsCount)
{
try