Skip to content

Commit 8fffd57

Browse files
authored
Add SpanSplitEnumerator.Source (#113673)
1 parent e377d65 commit 8fffd57

File tree

3 files changed

+24
-17
lines changed

3 files changed

+24
-17
lines changed

src/libraries/System.Memory/ref/System.Memory.cs

+1
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ public static void Sort<TKey, TValue, TComparer>(this System.Span<TKey> keys, Sy
518518
private object _dummy;
519519
private int _dummyPrimitive;
520520
public readonly System.Range Current { get { throw null; } }
521+
public readonly System.ReadOnlySpan<T> Source { get { throw null; } }
521522
public System.MemoryExtensions.SpanSplitEnumerator<T> GetEnumerator() { throw null; }
522523
public bool MoveNext() { throw null; }
523524
}

src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs

+21-17
Original file line numberDiff line numberDiff line change
@@ -5822,7 +5822,7 @@ private static bool TryWrite<TArg0, TArg1, TArg2>(Span<char> destination, IForma
58225822
public ref struct SpanSplitEnumerator<T> where T : IEquatable<T>
58235823
{
58245824
/// <summary>The input span being split.</summary>
5825-
private readonly ReadOnlySpan<T> _span;
5825+
private readonly ReadOnlySpan<T> _source;
58265826

58275827
/// <summary>A single separator to use when <see cref="_splitMode"/> is <see cref="SpanSplitEnumeratorMode.SingleElement"/>.</summary>
58285828
private readonly T _separator = default!;
@@ -5836,25 +5836,29 @@ private static bool TryWrite<TArg0, TArg1, TArg2>(Span<char> destination, IForma
58365836

58375837
/// <summary>Mode that dictates how the instance was configured and how its fields should be used in <see cref="MoveNext"/>.</summary>
58385838
private SpanSplitEnumeratorMode _splitMode;
5839-
/// <summary>The inclusive starting index in <see cref="_span"/> of the current range.</summary>
5839+
/// <summary>The inclusive starting index in <see cref="_source"/> of the current range.</summary>
58405840
private int _startCurrent = 0;
5841-
/// <summary>The exclusive ending index in <see cref="_span"/> of the current range.</summary>
5841+
/// <summary>The exclusive ending index in <see cref="_source"/> of the current range.</summary>
58425842
private int _endCurrent = 0;
5843-
/// <summary>The index in <see cref="_span"/> from which the next separator search should start.</summary>
5843+
/// <summary>The index in <see cref="_source"/> from which the next separator search should start.</summary>
58445844
private int _startNext = 0;
58455845

58465846
/// <summary>Gets an enumerator that allows for iteration over the split span.</summary>
58475847
/// <returns>Returns a <see cref="SpanSplitEnumerator{T}"/> that can be used to iterate over the split span.</returns>
58485848
public SpanSplitEnumerator<T> GetEnumerator() => this;
58495849

5850+
/// <summary>Gets the source span being enumerated.</summary>
5851+
/// <returns>Returns the <see cref="ReadOnlySpan{T}"/> that was provided when creating this enumerator.</returns>
5852+
public readonly ReadOnlySpan<T> Source => _source;
5853+
58505854
/// <summary>Gets the current element of the enumeration.</summary>
58515855
/// <returns>Returns a <see cref="Range"/> instance that indicates the bounds of the current element withing the source span.</returns>
58525856
public Range Current => new Range(_startCurrent, _endCurrent);
58535857

58545858
/// <summary>Initializes the enumerator for <see cref="SpanSplitEnumeratorMode.SearchValues"/>.</summary>
5855-
internal SpanSplitEnumerator(ReadOnlySpan<T> span, SearchValues<T> searchValues)
5859+
internal SpanSplitEnumerator(ReadOnlySpan<T> source, SearchValues<T> searchValues)
58565860
{
5857-
_span = span;
5861+
_source = source;
58585862
_splitMode = SpanSplitEnumeratorMode.SearchValues;
58595863
_searchValues = searchValues;
58605864
}
@@ -5865,9 +5869,9 @@ internal SpanSplitEnumerator(ReadOnlySpan<T> span, SearchValues<T> searchValues)
58655869
/// it will instead use <see cref="SpanSplitEnumeratorMode.SearchValues"/> with a cached <see cref="SearchValues{Char}"/>
58665870
/// for all whitespace characters.
58675871
/// </remarks>
5868-
internal SpanSplitEnumerator(ReadOnlySpan<T> span, ReadOnlySpan<T> separators)
5872+
internal SpanSplitEnumerator(ReadOnlySpan<T> source, ReadOnlySpan<T> separators)
58695873
{
5870-
_span = span;
5874+
_source = source;
58715875
if (typeof(T) == typeof(char) && separators.Length == 0)
58725876
{
58735877
_searchValues = Unsafe.As<SearchValues<T>>(string.SearchValuesStorage.WhiteSpaceChars);
@@ -5882,21 +5886,21 @@ internal SpanSplitEnumerator(ReadOnlySpan<T> span, ReadOnlySpan<T> separators)
58825886

58835887
/// <summary>Initializes the enumerator for <see cref="SpanSplitEnumeratorMode.Sequence"/> (or <see cref="SpanSplitEnumeratorMode.EmptySequence"/> if the separator is empty).</summary>
58845888
/// <remarks><paramref name="treatAsSingleSeparator"/> must be true.</remarks>
5885-
internal SpanSplitEnumerator(ReadOnlySpan<T> span, ReadOnlySpan<T> separator, bool treatAsSingleSeparator)
5889+
internal SpanSplitEnumerator(ReadOnlySpan<T> source, ReadOnlySpan<T> separator, bool treatAsSingleSeparator)
58865890
{
58875891
Debug.Assert(treatAsSingleSeparator, "Should only ever be called as true; exists to differentiate from separators overload");
58885892

5889-
_span = span;
5893+
_source = source;
58905894
_separatorBuffer = separator;
58915895
_splitMode = separator.Length == 0 ?
58925896
SpanSplitEnumeratorMode.EmptySequence :
58935897
SpanSplitEnumeratorMode.Sequence;
58945898
}
58955899

58965900
/// <summary>Initializes the enumerator for <see cref="SpanSplitEnumeratorMode.SingleElement"/>.</summary>
5897-
internal SpanSplitEnumerator(ReadOnlySpan<T> span, T separator)
5901+
internal SpanSplitEnumerator(ReadOnlySpan<T> source, T separator)
58985902
{
5899-
_span = span;
5903+
_source = source;
59005904
_separator = separator;
59015905
_splitMode = SpanSplitEnumeratorMode.SingleElement;
59025906
}
@@ -5915,17 +5919,17 @@ public bool MoveNext()
59155919
return false;
59165920

59175921
case SpanSplitEnumeratorMode.SingleElement:
5918-
separatorIndex = _span.Slice(_startNext).IndexOf(_separator);
5922+
separatorIndex = _source.Slice(_startNext).IndexOf(_separator);
59195923
separatorLength = 1;
59205924
break;
59215925

59225926
case SpanSplitEnumeratorMode.Any:
5923-
separatorIndex = _span.Slice(_startNext).IndexOfAny(_separatorBuffer);
5927+
separatorIndex = _source.Slice(_startNext).IndexOfAny(_separatorBuffer);
59245928
separatorLength = 1;
59255929
break;
59265930

59275931
case SpanSplitEnumeratorMode.Sequence:
5928-
separatorIndex = _span.Slice(_startNext).IndexOf(_separatorBuffer);
5932+
separatorIndex = _source.Slice(_startNext).IndexOf(_separatorBuffer);
59295933
separatorLength = _separatorBuffer.Length;
59305934
break;
59315935

@@ -5936,7 +5940,7 @@ public bool MoveNext()
59365940

59375941
default:
59385942
Debug.Assert(_splitMode == SpanSplitEnumeratorMode.SearchValues, $"Unknown split mode: {_splitMode}");
5939-
separatorIndex = _span.Slice(_startNext).IndexOfAny(_searchValues);
5943+
separatorIndex = _source.Slice(_startNext).IndexOfAny(_searchValues);
59405944
separatorLength = 1;
59415945
break;
59425946
}
@@ -5949,7 +5953,7 @@ public bool MoveNext()
59495953
}
59505954
else
59515955
{
5952-
_startNext = _endCurrent = _span.Length;
5956+
_startNext = _endCurrent = _source.Length;
59535957

59545958
// Set _splitMode to None so that subsequent MoveNext calls will return false.
59555959
_splitMode = SpanSplitEnumeratorMode.None;

src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs

+2
Original file line numberDiff line numberDiff line change
@@ -730,9 +730,11 @@ private static void AssertEqual(string[] items, ReadOnlySpan<char> source, Memor
730730
{
731731
Assert.True(enumerator.MoveNext());
732732
Assert.Equal(item, source[enumerator.Current].ToString());
733+
Assert.Equal(source.ToString(), enumerator.Source.ToString());
733734
}
734735

735736
Assert.False(enumerator.MoveNext());
737+
Assert.Equal(source.ToString(), enumerator.Source.ToString());
736738
}
737739
}
738740
}

0 commit comments

Comments
 (0)