_length = array.Length;
}
+ /// <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 (<0 or >&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).
/// <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 (<0 or >&eq;Length).
+ /// Thrown when the specified <paramref name="start"/> or end index is not in the range (<0 or >&eq;Length).
/// </exception>
public ReadOnlySpan(T[] array, int start, int length)
{
_length = array.Length;
}
+ /// <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 (<0 or >=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).
/// 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 (<0 or >&eq;Length).
+ /// Thrown when the specified <paramref name="start"/> or end index is not in the range (<0 or >=Length).
/// </exception>
public Span(T[] array, int start, int length)
{
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);
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);
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);
}
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);
}
}
+ 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];
}
}
- static void WhenSourceTypeLargerThaTargetAndOverflowsInt32ThrowsException()
+ static void WhenSourceTypeLargerThanTargetAndOverflowsInt32ThrowsException()
{
unsafe
{
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