using System; namespace gaemstone.Utility; public static class SpanExtensions { public static T? GetOrNull(this Span span, int index) where T : struct => GetOrNull((ReadOnlySpan)span, index); public static T? GetOrNull(this ReadOnlySpan span, int index) where T : struct => (index >= 0 && index < span.Length) ? span[index] : null; public static ReadOnlySpanSplitEnumerator Split(this ReadOnlySpan span, T splitOn) where T : IEquatable => new(span, splitOn); public ref struct ReadOnlySpanSplitEnumerator where T : IEquatable { private readonly ReadOnlySpan _span; private readonly T _splitOn; private int _index = -1; private int _end = -1; public ReadOnlySpanSplitEnumerator(ReadOnlySpan span, T splitOn) { _span = span; _splitOn = splitOn; } public ReadOnlySpanSplitEnumerator GetEnumerator() => this; public ReadOnlySpan Current => (_end >= 0) && (_end <= _span.Length) ? _span[_index.._end] : throw new InvalidOperationException(); public bool MoveNext() { if (_end == _span.Length) return false; _end++; _index = _end; while (_end < _span.Length && !_span[_end].Equals(_splitOn)) _end++; return true; } } }