diff --git a/src/Enumerators/Split/SpanSplitEnumerator.cs b/src/Enumerators/Split/SpanSplitEnumerator.cs index 3bd627e..0fafb2b 100644 --- a/src/Enumerators/Split/SpanSplitEnumerator.cs +++ b/src/Enumerators/Split/SpanSplitEnumerator.cs @@ -10,6 +10,7 @@ namespace SpanExtensions.Enumerators { ReadOnlySpan Span; readonly T Delimiter; + bool enumerationDone; /// /// Gets the element in the collection at the current position of the enumerator. @@ -26,6 +27,7 @@ public SpanSplitEnumerator(ReadOnlySpan source, T delimiter) Span = source; Delimiter = delimiter; Current = default; + enumerationDone = false; } /// @@ -42,16 +44,17 @@ public readonly SpanSplitEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; int index = span.IndexOf(Delimiter); if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } diff --git a/src/Enumerators/Split/SpanSplitStringSplitOptionsEnumerator.cs b/src/Enumerators/Split/SpanSplitStringSplitOptionsEnumerator.cs index 1fbccce..3248861 100644 --- a/src/Enumerators/Split/SpanSplitStringSplitOptionsEnumerator.cs +++ b/src/Enumerators/Split/SpanSplitStringSplitOptionsEnumerator.cs @@ -10,6 +10,7 @@ public ref struct SpanSplitStringSplitOptionsEnumerator ReadOnlySpan Span; readonly char Delimiter; readonly StringSplitOptions Options; + bool enumerationDone; /// /// Gets the element in the collection at the current position of the enumerator. @@ -28,6 +29,7 @@ public SpanSplitStringSplitOptionsEnumerator(ReadOnlySpan source, char del Delimiter = delimiter; Options = options; Current = default; + enumerationDone = false; } /// @@ -44,16 +46,17 @@ public readonly SpanSplitStringSplitOptionsEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; int index = span.IndexOf(Delimiter); if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } @@ -69,8 +72,20 @@ public bool MoveNext() if(Current.IsEmpty) { Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + return false; + } return MoveNext(); } + + Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + } + return true; } Span = span[(index + 1)..]; return true; diff --git a/src/Enumerators/Split/SpanSplitStringSplitOptionsWithCountEnumerator.cs b/src/Enumerators/Split/SpanSplitStringSplitOptionsWithCountEnumerator.cs index 11a4d09..333c0bb 100644 --- a/src/Enumerators/Split/SpanSplitStringSplitOptionsWithCountEnumerator.cs +++ b/src/Enumerators/Split/SpanSplitStringSplitOptionsWithCountEnumerator.cs @@ -13,6 +13,7 @@ public ref struct SpanSplitStringSplitOptionsWithCountEnumerator readonly int Count; readonly CountExceedingBehaviour CountExceedingBehaviour; int currentCount; + bool enumerationDone; readonly int CountMinusOne; /// @@ -37,6 +38,7 @@ public SpanSplitStringSplitOptionsWithCountEnumerator(ReadOnlySpan source, Options = options; Current = default; currentCount = 0; + enumerationDone = false; CountMinusOne = Math.Max(Count - 1, 0); } @@ -54,11 +56,12 @@ public readonly SpanSplitStringSplitOptionsWithCountEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; if(currentCount == Count) { return false; @@ -87,7 +90,7 @@ public bool MoveNext() } if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } @@ -105,8 +108,20 @@ public bool MoveNext() if(Current.IsEmpty) { Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + return false; + } return MoveNext(); } + + Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + } + return true; } Span = span[(index + 1)..]; return true; diff --git a/src/Enumerators/Split/SpanSplitWithCountEnumerator.cs b/src/Enumerators/Split/SpanSplitWithCountEnumerator.cs index d9bf6a8..4c71b36 100644 --- a/src/Enumerators/Split/SpanSplitWithCountEnumerator.cs +++ b/src/Enumerators/Split/SpanSplitWithCountEnumerator.cs @@ -13,6 +13,7 @@ namespace SpanExtensions.Enumerators readonly int Count; readonly CountExceedingBehaviour CountExceedingBehaviour; int currentCount; + bool enumerationDone; readonly int CountMinusOne; /// @@ -35,6 +36,7 @@ public SpanSplitWithCountEnumerator(ReadOnlySpan source, T delimiter, int cou CountExceedingBehaviour = countExceedingBehaviour; Current = default; currentCount = 0; + enumerationDone = false; CountMinusOne = Math.Max(Count - 1, 0); } @@ -52,11 +54,12 @@ public readonly SpanSplitWithCountEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; if(currentCount == Count) { return false; @@ -84,7 +87,7 @@ public bool MoveNext() } if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } diff --git a/src/Enumerators/SplitAny/SpanSplitAnyEnumerator.cs b/src/Enumerators/SplitAny/SpanSplitAnyEnumerator.cs index 2a54d65..104361b 100644 --- a/src/Enumerators/SplitAny/SpanSplitAnyEnumerator.cs +++ b/src/Enumerators/SplitAny/SpanSplitAnyEnumerator.cs @@ -11,6 +11,7 @@ namespace SpanExtensions.Enumerators { ReadOnlySpan Span; readonly ReadOnlySpan Delimiters; + bool enumerationDone; /// /// Gets the element in the collection at the current position of the enumerator. @@ -27,6 +28,7 @@ public SpanSplitAnyEnumerator(ReadOnlySpan source, ReadOnlySpan delimiters Span = source; Delimiters = delimiters; Current = default; + enumerationDone = false; } /// @@ -43,16 +45,17 @@ public readonly SpanSplitAnyEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; int index = span.IndexOfAny(Delimiters); if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } diff --git a/src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsEnumerator.cs b/src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsEnumerator.cs index 4c4f73a..e49cd02 100644 --- a/src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsEnumerator.cs +++ b/src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsEnumerator.cs @@ -10,6 +10,7 @@ public ref struct SpanSplitAnyStringSplitOptionsEnumerator ReadOnlySpan Span; readonly ReadOnlySpan Delimiters; readonly StringSplitOptions Options; + bool enumerationDone; /// /// Gets the element in the collection at the current position of the enumerator. @@ -28,6 +29,7 @@ public SpanSplitAnyStringSplitOptionsEnumerator(ReadOnlySpan source, ReadO Delimiters = delimiters; Options = options; Current = default; + enumerationDone = false; } /// @@ -44,16 +46,17 @@ public readonly SpanSplitAnyStringSplitOptionsEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; int index = span.IndexOfAny(Delimiters); if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } @@ -70,8 +73,20 @@ public bool MoveNext() if(Current.IsEmpty) { Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + return false; + } return MoveNext(); } + + Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + } + return true; } Span = span[(index + 1)..]; return true; diff --git a/src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsWithCountEnumerator.cs b/src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsWithCountEnumerator.cs index 4ee0f0c..a7b7129 100644 --- a/src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsWithCountEnumerator.cs +++ b/src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsWithCountEnumerator.cs @@ -13,6 +13,7 @@ public ref struct SpanSplitAnyStringSplitOptionsWithCountEnumerator readonly int Count; readonly CountExceedingBehaviour CountExceedingBehaviour; int currentCount; + bool enumerationDone; readonly int CountMinusOne; /// @@ -37,6 +38,7 @@ public SpanSplitAnyStringSplitOptionsWithCountEnumerator(ReadOnlySpan sour CountExceedingBehaviour = countExceedingBehaviour; Current = default; currentCount = 0; + enumerationDone = false; CountMinusOne = Math.Max(Count - 1, 0); } @@ -54,11 +56,12 @@ public readonly SpanSplitAnyStringSplitOptionsWithCountEnumerator GetEnumerator( /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; if(currentCount == Count) { return false; @@ -87,7 +90,7 @@ public bool MoveNext() } if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } @@ -105,8 +108,20 @@ public bool MoveNext() if(Current.IsEmpty) { Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + return false; + } return MoveNext(); } + + Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + } + return true; } Span = span[(index + 1)..]; return true; diff --git a/src/Enumerators/SplitAny/SpanSplitAnyWithCountEnumerator.cs b/src/Enumerators/SplitAny/SpanSplitAnyWithCountEnumerator.cs index 50656e5..243bbe8 100644 --- a/src/Enumerators/SplitAny/SpanSplitAnyWithCountEnumerator.cs +++ b/src/Enumerators/SplitAny/SpanSplitAnyWithCountEnumerator.cs @@ -13,6 +13,7 @@ namespace SpanExtensions.Enumerators readonly int Count; readonly CountExceedingBehaviour CountExceedingBehaviour; int currentCount; + bool enumerationDone; readonly int CountMinusOne; /// @@ -35,6 +36,7 @@ public SpanSplitAnyWithCountEnumerator(ReadOnlySpan source, ReadOnlySpan d CountExceedingBehaviour = countExceedingBehaviour; Current = default; currentCount = 0; + enumerationDone = false; CountMinusOne = Math.Max(Count - 1, 0); } @@ -52,11 +54,12 @@ public readonly SpanSplitAnyWithCountEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; if(currentCount == Count) { return false; @@ -84,7 +87,7 @@ public bool MoveNext() } if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } diff --git a/src/Enumerators/SplitSequence/SpanSplitSequenceEnumerator.cs b/src/Enumerators/SplitSequence/SpanSplitSequenceEnumerator.cs index f55c4a1..013936d 100644 --- a/src/Enumerators/SplitSequence/SpanSplitSequenceEnumerator.cs +++ b/src/Enumerators/SplitSequence/SpanSplitSequenceEnumerator.cs @@ -10,6 +10,7 @@ namespace SpanExtensions.Enumerators { ReadOnlySpan Span; readonly ReadOnlySpan Delimiter; + bool enumerationDone; /// /// Gets the element in the collection at the current position of the enumerator. @@ -26,6 +27,7 @@ public SpanSplitSequenceEnumerator(ReadOnlySpan source, ReadOnlySpan delim Span = source; Delimiter = delimiter; Current = default; + enumerationDone = false; } /// @@ -42,16 +44,17 @@ public readonly SpanSplitSequenceEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; int index = span.IndexOf(Delimiter); if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } diff --git a/src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsEnumerator.cs b/src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsEnumerator.cs index eacc5e5..a7dad72 100644 --- a/src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsEnumerator.cs +++ b/src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsEnumerator.cs @@ -10,6 +10,7 @@ public ref struct SpanSplitSequenceStringSplitOptionsEnumerator ReadOnlySpan Span; readonly ReadOnlySpan Delimiter; readonly StringSplitOptions Options; + bool enumerationDone; /// /// Gets the element in the collection at the current position of the enumerator. @@ -28,6 +29,7 @@ public SpanSplitSequenceStringSplitOptionsEnumerator(ReadOnlySpan source, Delimiter = delimiter; Options = options; Current = default; + enumerationDone = false; } /// @@ -44,16 +46,17 @@ public readonly SpanSplitSequenceStringSplitOptionsEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; int index = span.IndexOf(Delimiter); if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } @@ -70,8 +73,20 @@ public bool MoveNext() if(Current.IsEmpty) { Span = span[(index + Delimiter.Length)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + return false; + } return MoveNext(); } + + Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + } + return true; } Span = span[(index + Delimiter.Length)..]; return true; diff --git a/src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsWithCountEnumerator.cs b/src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsWithCountEnumerator.cs index b12147d..0ced8f0 100644 --- a/src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsWithCountEnumerator.cs +++ b/src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsWithCountEnumerator.cs @@ -13,8 +13,8 @@ public ref struct SpanSplitSequenceStringSplitOptionsWithCountEnumerator readonly int Count; readonly CountExceedingBehaviour CountExceedingBehaviour; int currentCount; + bool enumerationDone; readonly int CountMinusOne; - /// /// Gets the element in the collection at the current position of the enumerator. /// @@ -37,6 +37,7 @@ public SpanSplitSequenceStringSplitOptionsWithCountEnumerator(ReadOnlySpan CountExceedingBehaviour = countExceedingBehaviour; Current = default; currentCount = 0; + enumerationDone = false; CountMinusOne = Math.Max(Count - 1, 0); } @@ -54,11 +55,12 @@ public readonly SpanSplitSequenceStringSplitOptionsWithCountEnumerator GetEnumer /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; if(currentCount == Count) { return false; @@ -87,7 +89,7 @@ public bool MoveNext() } if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; } @@ -105,8 +107,20 @@ public bool MoveNext() if(Current.IsEmpty) { Span = span[(index + Delimiter.Length)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + return false; + } return MoveNext(); } + + Span = span[(index + 1)..]; + if(Span.IsEmpty) + { + enumerationDone = true; + } + return true; } Span = span[(index + Delimiter.Length)..]; return true; diff --git a/src/Enumerators/SplitSequence/SpanSplitSequenceWithCountEnumerator.cs b/src/Enumerators/SplitSequence/SpanSplitSequenceWithCountEnumerator.cs index dbfbb0b..7e4d86e 100644 --- a/src/Enumerators/SplitSequence/SpanSplitSequenceWithCountEnumerator.cs +++ b/src/Enumerators/SplitSequence/SpanSplitSequenceWithCountEnumerator.cs @@ -13,6 +13,7 @@ namespace SpanExtensions.Enumerators readonly int Count; readonly CountExceedingBehaviour CountExceedingBehaviour; int currentCount; + bool enumerationDone; readonly int CountMinusOne; /// @@ -35,6 +36,7 @@ public SpanSplitSequenceWithCountEnumerator(ReadOnlySpan source, ReadOnlySpan CountExceedingBehaviour = countExceedingBehaviour; Current = default; currentCount = 0; + enumerationDone = false; CountMinusOne = Math.Max(Count - 1, 0); } @@ -52,11 +54,12 @@ public readonly SpanSplitSequenceWithCountEnumerator GetEnumerator() /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { - ReadOnlySpan span = Span; - if(span.IsEmpty) + if(enumerationDone) { return false; } + + ReadOnlySpan span = Span; if(currentCount == Count) { return false; @@ -84,7 +87,7 @@ public bool MoveNext() } if(index == -1 || index >= span.Length) { - Span = ReadOnlySpan.Empty; + enumerationDone = true; Current = span; return true; }