diff --git a/Changelog.md b/Changelog.md index b82a780..a426767 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres not (yet) to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.5.1] - 2024-12-14 + +### Fixed + +- incorrect ranges returned by the range-based Split method for versions prior to .Net 9. + +### Changed + +- moved MemoryExtensions containing range-based Split method for versions prior to .Net 9 from `System` to `SpanExtensions`. +- grammatical issues in some documentation comments. + ## [1.5] - 2024-11-12 ### Added diff --git a/src/Enumerators/System/SpanSplitEnumerator.cs b/src/Enumerators/System/SpanSplitEnumerator.cs index e07af58..d4a4f68 100644 --- a/src/Enumerators/System/SpanSplitEnumerator.cs +++ b/src/Enumerators/System/SpanSplitEnumerator.cs @@ -1,10 +1,11 @@ -using System.Buffers; +using System; +using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; #if !NET9_0_OR_GREATER -namespace System +namespace SpanExtensions { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member public static partial class MemoryExtensions @@ -23,27 +24,35 @@ public static partial class MemoryExtensions readonly SearchValues SearchValues = null!; #endif + int currentStartIndex; + int currentEndIndex; + int nextStartIndex; /// /// Gets the current element of the enumeration. /// - /// Returns a instance that indicates the bounds of the current element withing the source span. - public Range Current { get; internal set; } + /// Returns a instance that indicates the bounds of the current element within the source span. + public readonly Range Current => new Range(currentStartIndex, currentEndIndex); internal SpanSplitEnumerator(ReadOnlySpan source, T delimiter) { Span = source; Delimiter = delimiter; - Current = new Range(0, 0); DelimiterSpan = default; mode = SpanSplitEnumeratorMode.Delimiter; + currentStartIndex = 0; + currentEndIndex = 0; + nextStartIndex = 0; } + internal SpanSplitEnumerator(ReadOnlySpan source, ReadOnlySpan delimiter, SpanSplitEnumeratorMode mode) { Span = source; DelimiterSpan = delimiter; - Current = new Range(0, 0); Delimiter = default!; this.mode = mode; + currentStartIndex = 0; + currentEndIndex = 0; + nextStartIndex = 0; } #if NET8_0 @@ -52,9 +61,11 @@ internal SpanSplitEnumerator(ReadOnlySpan source, SearchValues searchValue Span = source; Delimiter = default!; SearchValues = searchValues; - Current = new Range(0, 0); DelimiterSpan = default; mode = SpanSplitEnumeratorMode.Delimiter; + currentStartIndex = 0; + currentEndIndex = 0; + nextStartIndex = 0; } #endif /// @@ -77,17 +88,17 @@ public bool MoveNext() switch(mode) { case SpanSplitEnumeratorMode.Delimiter: - index = Span[Current.Start..].IndexOf(Delimiter); + index = Span[nextStartIndex..].IndexOf(Delimiter); length = 1; break; case SpanSplitEnumeratorMode.Any: - index = Span[Current.Start..].IndexOfAny(DelimiterSpan); + index = Span[nextStartIndex..].IndexOfAny(DelimiterSpan); length = 1; break; case SpanSplitEnumeratorMode.Sequence: - index = Span[Current.Start..].IndexOf(DelimiterSpan); + index = Span[nextStartIndex..].IndexOf(DelimiterSpan); length = DelimiterSpan.Length; break; @@ -98,7 +109,7 @@ public bool MoveNext() #if NET8_0 case SpanSplitEnumeratorMode.SearchValues: - index = Span[Current.Start..].IndexOfAny(SearchValues); + index = Span[nextStartIndex..].IndexOfAny(SearchValues); length = 1; break; #endif @@ -106,15 +117,20 @@ public bool MoveNext() return false; } + currentStartIndex = nextStartIndex; + if(index < 0) { - Current = new Range(Span.Length, Span.Length); + currentEndIndex = Span.Length; + nextStartIndex = Span.Length; + mode = (SpanSplitEnumeratorMode)(-1); return true; } - Current = new Range(Current.End.Value + length, Current.Start.Value + index); - + currentEndIndex = currentStartIndex + index; + nextStartIndex = currentEndIndex + length; + return true; } } @@ -129,5 +145,4 @@ internal enum SpanSplitEnumeratorMode } } } - #endif \ No newline at end of file diff --git a/src/Extensions/ReadOnlySpan/Span/Split.cs b/src/Extensions/ReadOnlySpan/Span/Split.cs index 3807256..550804f 100644 --- a/src/Extensions/ReadOnlySpan/Span/Split.cs +++ b/src/Extensions/ReadOnlySpan/Span/Split.cs @@ -1,10 +1,11 @@ -using System.Buffers; +using System; +using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; #if !NET9_0_OR_GREATER -namespace System +namespace SpanExtensions { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member public static partial class MemoryExtensions diff --git a/src/Extensions/Span/Span/Split.cs b/src/Extensions/Span/Span/Split.cs index 7ae44a8..f218aca 100644 --- a/src/Extensions/Span/Span/Split.cs +++ b/src/Extensions/Span/Span/Split.cs @@ -1,10 +1,11 @@ -using System.Buffers; +using System; +using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; #if !NET9_0_OR_GREATER -namespace System +namespace SpanExtensions { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member public static partial class MemoryExtensions diff --git a/src/SpanExtensions.csproj b/src/SpanExtensions.csproj index 2ada243..ba1cf8e 100644 --- a/src/SpanExtensions.csproj +++ b/src/SpanExtensions.csproj @@ -1,66 +1,66 @@  - - net9.0;net8.0;net7.0;net6.0;net5.0;netstandard2.1 - disable - enable - True - AnyCPU - Span Extensions - dragon-cs - draconware - - ReadonlySpan<T> and Span<T> are great Types in C#, but unfortunately working with them can sometimes be sort of a hassle and some use cases seem straight up impossible, even though they are not. + + net9.0;net8.0;net7.0;net6.0;net5.0;netstandard2.1 + disable + enable + True + AnyCPU + Span Extensions + dragon-cs + draconware + + ReadonlySpan<T> and Span<T> are great Types in C#, but unfortunately working with them can sometimes be sort of a hassle and some use cases seem straight up impossible, even though they are not. - SpanExtensions.Net aims to help developers use ReadonlySpan<T> and Span<T> more productively, efficiently and safely and write overall more performant Programs. + SpanExtensions.Net aims to help developers use ReadonlySpan<T> and Span<T> more productively, efficiently and safely and write overall more performant Programs. - Never again switch back to using string instead of ReadonlySpan<T>, just because the method you seek is not supported. - - https://github.com/draconware-dev/SpanExtensions.Net - True - Copyright (c) 2024 draconware-dev - Span;Performance;Extension;String - https://github.com/draconware-dev/SpanExtensions.Net/blob/main/Changelog.md - LICENSE - 1.5 - SpanExtensions.Net - README.md - icon.png - + Never again switch back to using string instead of ReadonlySpan<T>, just because the method you seek is not supported. + + https://github.com/draconware-dev/SpanExtensions.Net + True + Copyright (c) 2024 draconware-dev + Span;Performance;Extension;String + https://github.com/draconware-dev/SpanExtensions.Net/blob/main/Changelog.md + LICENSE + 1.5.1 + SpanExtensions.Net + README.md + icon.png + - - portable - + + portable + - - portable - + + portable + - - portable - + + portable + - - portable - + + portable + - - - True - \ - - - True - \ - Always - - + + + True + \ + + + True + \ + Always + + - - - True - \ - - + + + True + \ + +