<Member Name="Equals(System.ReadOnlySpan<T>)" />
<Member Name="TryCopyTo(System.Span<T>)" />
</Type>
- <Type Name="System.SpanExtensions">
+ <Type Name="System.SpanExtensions" Condition="FEATURE_SPAN_OF_T">
<Member Name="AsBytes<T>(System.Span<T>)" />
<Member Name="AsBytes<T>(System.ReadOnlySpan<T>)" />
<Member Name="NonPortableCast<TFrom,TTo>(System.Span<TFrom>)" />
<Member Name="NonPortableCast<TFrom,TTo>(System.ReadOnlySpan<TFrom>)" />
</Type>
+ <Type Name="System.ReadOnlySpanExtensions" Condition="FEATURE_SPAN_OF_T">
+ <Member Name="Slice(System.String)" />
+ <Member Name="Slice(System.String,System.Int32)" />
+ <Member Name="Slice(System.String,System.Int32,System.Int32)" />
+ </Type>
</Assembly>
</ThinModel>
return true;
}
}
+
+ public static class ReadOnlySpanExtensions
+ {
+ /// <summary>
+ /// Creates a new readonly span over the portion of the target string.
+ /// </summary>
+ /// <param name="text">The target string.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ public static ReadOnlySpan<char> Slice(this string text)
+ {
+ if (text == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+
+ return new ReadOnlySpan<char>(ref text.GetFirstCharRef(), text.Length);
+ }
+
+ /// <summary>
+ /// Creates a new readonly span over the portion of the target string, beginning at 'start'.
+ /// </summary>
+ /// <param name="text">The target string.</param>
+ /// <param name="start">The index at which to begin this slice.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> index is not in range (<0 or >Length).
+ /// </exception>
+ public static ReadOnlySpan<char> Slice(this string text, int start)
+ {
+ if (text == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+ if ((uint)start > (uint)text.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ return new ReadOnlySpan<char>(ref JitHelpers.AddByRef(ref text.GetFirstCharRef(), start), text.Length - start);
+ }
+
+ /// <summary>
+ /// Creates a new readonly span over the portion of the target string, beginning at <paramref name="start"/>, of given <paramref name="length"/>.
+ /// </summary>
+ /// <param name="text">The target string.</param>
+ /// <param name="start">The index at which to begin this slice.</param>
+ /// <param name="length">The number of items in the span.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> 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).
+ /// </exception>
+ public static ReadOnlySpan<char> Slice(this string text, int start, int length)
+ {
+ if (text == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+ if ((uint)start >= (uint)text.Length || (uint)length > (uint)(text.Length - start))
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ return new ReadOnlySpan<char>(ref JitHelpers.AddByRef(ref text.GetFirstCharRef(), start), length);
+ }
+ }
}
\ No newline at end of file
byte* dstPtr = (byte*) dest;
Buffer.Memcpy(dstPtr, srcPtr, len);
}
- }
+ }
+
+ internal ref char GetFirstCharRef() {
+ return ref m_firstChar;
+ }
}
}
addValueFactory,
updateValueFactory,
concurrencyLevel,
+ text,
}
Test(WhenSourceDoesntFitIntoTargetLengthIsZero, "WhenSourceDoesntFitIntoTargetLengthIsZero", ref failedTestsCount);
Test(WhenSourceFitsIntoTargetOnceLengthIsOne, "WhenSourceFitsIntoTargetOnceLengthIsOne", ref failedTestsCount);
Test(WhenSourceTypeLargerThaTargetAndOverflowsInt32ThrowsException, "WhenSourceTypeLargerThaTargetAndOverflowsInt32ThrowsException", ref failedTestsCount);
+ Test(CanCreateSpanFromString, "CanCreateSpanFromString", ref failedTestsCount);
Console.WriteLine(string.Format("{0} tests has failed", failedTestsCount));
Environment.Exit(failedTestsCount);
}
}
+ static void CanCreateSpanFromString()
+ {
+ const string fullText = "new Span<byte>()";
+ var spanFromFull = fullText.Slice();
+ AssertEqualContent(fullText, spanFromFull);
+
+ string firstHalfOfString = fullText.Substring(0, fullText.Length / 2);
+ var spanFromFirstHalf = fullText.Slice(0, fullText.Length / 2);
+ AssertEqualContent(firstHalfOfString, spanFromFirstHalf);
+
+ string secondHalfOfString = fullText.Substring(fullText.Length / 2);
+ var spanFromSecondHalf = fullText.Slice(fullText.Length / 2);
+ AssertEqualContent(secondHalfOfString, spanFromSecondHalf);
+ }
+
static void Test(Action test, string testName, ref int failedTestsCount)
{
try
throw new Exception(string.Format("Values were not equal! {0} and {1}", left, right));
}
}
+
+ static void AssertEqualContent(string text, ReadOnlySpan<char> span)
+ {
+ AssertEqual(text.Length, span.Length);
+ for (int i = 0; i < text.Length; i++)
+ {
+ AssertEqual(text[i], span[i]);
+ }
+ }
}