Created
August 30, 2023 19:11
-
-
Save AntonC9018/35a5a2cad4b3fedeb6e95bf5b2462eaa to your computer and use it in GitHub Desktop.
Split that can be used on ReadOnlySpan<char> without allocations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class SpanExtensions | |
{ | |
public static Splitter<T> Splitter<T>( | |
this ReadOnlySpan<T> span, | |
ReadOnlySpan<T> delimiter) | |
where T : IEquatable<T> | |
{ | |
return new(span, delimiter); | |
} | |
} | |
public readonly ref struct Splitter<T> | |
where T : IEquatable<T> | |
{ | |
public Splitter(ReadOnlySpan<T> span, ReadOnlySpan<T> delimiter) | |
{ | |
Span = span; | |
Delimiter = delimiter; | |
} | |
public ReadOnlySpan<T> Span { get; } | |
public ReadOnlySpan<T> Delimiter { get; } | |
public Enumerator GetEnumerator() => new(this); | |
public ref struct Enumerator | |
{ | |
private readonly Splitter<T> _splitter; | |
private int _currentIndex; | |
private int _currentLength; | |
public Enumerator(Splitter<T> splitter) | |
{ | |
_splitter = splitter; | |
_currentIndex = 0; | |
_currentLength = -1; | |
} | |
public ReadOnlySpan<T> Current => _splitter.Span.Slice(_currentIndex, _currentLength); | |
public bool MoveNext() | |
{ | |
_currentIndex += _currentLength + 1; | |
if (_currentIndex >= _splitter.Span.Length) | |
return false; | |
var spanLeft = _splitter.Span[_currentIndex ..]; | |
_currentLength = spanLeft.IndexOf(_splitter.Delimiter); | |
if (_currentLength == -1) | |
_currentLength = spanLeft.Length; | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment