Skip to content

Commit 14c3bde

Browse files
committed
methods accept now CountExceedingBehaviour
1 parent 5c83f8b commit 14c3bde

7 files changed

+167
-30
lines changed

src/Enumerators/Split/SpanSplitStringSplitOptionsWithCountEnumerator.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public ref struct SpanSplitStringSplitOptionsWithCountEnumerator
1111
readonly char Delimiter;
1212
readonly StringSplitOptions Options;
1313
readonly int Count;
14+
readonly CountExceedingBehaviour CountExceedingBehaviour;
1415
int currentCount;
16+
readonly int CountMinusOne;
1517

1618
/// <summary>
1719
/// Gets the element in the collection at the current position of the enumerator.
@@ -25,14 +27,17 @@ public ref struct SpanSplitStringSplitOptionsWithCountEnumerator
2527
/// <param name="delimiter">A <see cref="char"/> that delimits the various sub-ReadOnlySpans in <paramref name="source"/>.</param>
2628
/// <param name="count">The maximum number of sub-ReadOnlySpans to split into.</param>
2729
/// <param name="options">A bitwise combination of the enumeration values that specifies whether to trim results and include empty results.</param>
28-
public SpanSplitStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, char delimiter, int count, StringSplitOptions options)
30+
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
31+
public SpanSplitStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, char delimiter, int count, StringSplitOptions options, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.CutLastElements)
2932
{
3033
Span = source;
3134
Delimiter = delimiter;
3235
Count = count;
36+
CountExceedingBehaviour = countExceedingBehaviour;
3337
Options = options;
3438
Current = default;
3539
currentCount = 0;
40+
CountMinusOne = Math.Max(Count - 1, 0);
3641
}
3742

3843
/// <summary>
@@ -60,6 +65,26 @@ public bool MoveNext()
6065
}
6166
int index = span.IndexOf(Delimiter);
6267

68+
switch(CountExceedingBehaviour)
69+
{
70+
case CountExceedingBehaviour.CutLastElements:
71+
break;
72+
case CountExceedingBehaviour.AppendLastElements:
73+
if(currentCount == CountMinusOne)
74+
{
75+
ReadOnlySpan<char> lower = span[..index];
76+
ReadOnlySpan<char> upper = span[(index + 1)..];
77+
Span<char> temp = new char[lower.Length + upper.Length];
78+
lower.CopyTo(temp[..index]);
79+
upper.CopyTo(temp[index..]);
80+
Current = temp;
81+
currentCount++;
82+
return true;
83+
}
84+
break;
85+
default:
86+
throw new InvalidCountExceedingBehaviourException(CountExceedingBehaviour);
87+
}
6388
if(index == -1 || index >= span.Length)
6489
{
6590
Span = ReadOnlySpan<char>.Empty;

src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsWithCountEnumerator.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public ref struct SpanSplitAnyStringSplitOptionsWithCountEnumerator
1111
readonly ReadOnlySpan<char> Delimiters;
1212
readonly StringSplitOptions Options;
1313
readonly int Count;
14+
readonly CountExceedingBehaviour CountExceedingBehaviour;
1415
int currentCount;
16+
readonly int CountMinusOne;
1517

1618
/// <summary>
1719
/// Gets the element in the collection at the current position of the enumerator.
@@ -25,14 +27,17 @@ public ref struct SpanSplitAnyStringSplitOptionsWithCountEnumerator
2527
/// <param name="delimiters">A <see cref="ReadOnlySpan{Char}"/> with the <see cref="char"/> elements that delimit the various sub-ReadOnlySpans in <paramref name="source"/>.</param>
2628
/// <param name="count">The maximum number of sub-ReadOnlySpans to split into.</param>
2729
/// <param name="options">A bitwise combination of the enumeration values that specifies whether to trim results and include empty results.</param>
28-
public SpanSplitAnyStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, ReadOnlySpan<char> delimiters, int count, StringSplitOptions options)
30+
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
31+
public SpanSplitAnyStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, ReadOnlySpan<char> delimiters, int count, StringSplitOptions options, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.CutLastElements)
2932
{
3033
Span = source;
3134
Delimiters = delimiters;
3235
Count = count;
3336
Options = options;
37+
CountExceedingBehaviour = countExceedingBehaviour;
3438
Current = default;
3539
currentCount = 0;
40+
CountMinusOne = Math.Max(Count - 1, 0);
3641
}
3742

3843
/// <summary>
@@ -60,6 +65,26 @@ public bool MoveNext()
6065
}
6166
int index = span.IndexOfAny(Delimiters);
6267

68+
switch(CountExceedingBehaviour)
69+
{
70+
case CountExceedingBehaviour.CutLastElements:
71+
break;
72+
case CountExceedingBehaviour.AppendLastElements:
73+
if(currentCount == CountMinusOne)
74+
{
75+
ReadOnlySpan<char> lower = span[..index];
76+
ReadOnlySpan<char> upper = span[(index + 1)..];
77+
Span<char> temp = new char[lower.Length + upper.Length];
78+
lower.CopyTo(temp[..index]);
79+
upper.CopyTo(temp[index..]);
80+
Current = temp;
81+
currentCount++;
82+
return true;
83+
}
84+
break;
85+
default:
86+
throw new InvalidCountExceedingBehaviourException(CountExceedingBehaviour);
87+
}
6388
if(index == -1 || index >= span.Length)
6489
{
6590
Span = ReadOnlySpan<char>.Empty;

src/Enumerators/SplitAny/SpanSplitAnyWithCountEnumerator.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ namespace SpanExtensions.Enumerators
1111
ReadOnlySpan<T> Span;
1212
readonly ReadOnlySpan<T> Delimiters;
1313
readonly int Count;
14+
readonly CountExceedingBehaviour CountExceedingBehaviour;
1415
int currentCount;
16+
readonly int CountMinusOne;
1517

1618
/// <summary>
1719
/// Gets the element in the collection at the current position of the enumerator.
@@ -24,13 +26,16 @@ namespace SpanExtensions.Enumerators
2426
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to be split.</param>
2527
/// <param name="delimiters">A <see cref="ReadOnlySpan{T}"/> with the instances of <typeparamref name="T"/> that delimit the various sub-ReadOnlySpans in <paramref name="source"/>.</param>
2628
/// <param name="count">The maximum number of sub-ReadOnlySpans to split into.</param>
27-
public SpanSplitAnyWithCountEnumerator(ReadOnlySpan<T> source, ReadOnlySpan<T> delimiters, int count)
29+
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
30+
public SpanSplitAnyWithCountEnumerator(ReadOnlySpan<T> source, ReadOnlySpan<T> delimiters, int count, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.CutLastElements)
2831
{
2932
Span = source;
3033
Delimiters = delimiters;
3134
Count = count;
35+
CountExceedingBehaviour = countExceedingBehaviour;
3236
Current = default;
3337
currentCount = 0;
38+
CountMinusOne = Math.Max(Count - 1, 0);
3439
}
3540

3641
/// <summary>
@@ -57,6 +62,26 @@ public bool MoveNext()
5762
return false;
5863
}
5964
int index = span.IndexOfAny(Delimiters);
65+
switch(CountExceedingBehaviour)
66+
{
67+
case CountExceedingBehaviour.CutLastElements:
68+
break;
69+
case CountExceedingBehaviour.AppendLastElements:
70+
if(currentCount == CountMinusOne)
71+
{
72+
ReadOnlySpan<T> lower = span[..index];
73+
ReadOnlySpan<T> upper = span[(index + 1)..];
74+
Span<T> temp = new T[lower.Length + upper.Length];
75+
lower.CopyTo(temp[..index]);
76+
upper.CopyTo(temp[index..]);
77+
Current = temp;
78+
currentCount++;
79+
return true;
80+
}
81+
break;
82+
default:
83+
throw new InvalidCountExceedingBehaviourException(CountExceedingBehaviour);
84+
}
6085
if(index == -1 || index >= span.Length)
6186
{
6287
Span = ReadOnlySpan<T>.Empty;

src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsWithCountEnumerator.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public ref struct SpanSplitSequenceStringSplitOptionsWithCountEnumerator
1111
readonly ReadOnlySpan<char> Delimiter;
1212
readonly StringSplitOptions Options;
1313
readonly int Count;
14+
readonly CountExceedingBehaviour CountExceedingBehaviour;
1415
int currentCount;
16+
readonly int CountMinusOne;
1517

1618
/// <summary>
1719
/// Gets the element in the collection at the current position of the enumerator.
@@ -25,14 +27,17 @@ public ref struct SpanSplitSequenceStringSplitOptionsWithCountEnumerator
2527
/// <param name="delimiter">An instance of <see cref="ReadOnlySpan{Char}"/> that delimits the various sub-ReadOnlySpans in <paramref name="source"/>.</param>
2628
/// <param name="options">A bitwise combination of the enumeration values that specifies whether to trim results and include empty results.</param>
2729
/// <param name="count">The maximum number of sub-ReadOnlySpans to split into.</param>
28-
public SpanSplitSequenceStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, ReadOnlySpan<char> delimiter, int count, StringSplitOptions options)
30+
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
31+
public SpanSplitSequenceStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, ReadOnlySpan<char> delimiter, int count, StringSplitOptions options, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.CutLastElements)
2932
{
3033
Span = source;
3134
Delimiter = delimiter;
3235
Count = count;
3336
Options = options;
37+
CountExceedingBehaviour = countExceedingBehaviour;
3438
Current = default;
3539
currentCount = 0;
40+
CountMinusOne = Math.Max(Count - 1, 0);
3641
}
3742

3843
/// <summary>
@@ -60,6 +65,26 @@ public bool MoveNext()
6065
}
6166
int index = span.IndexOf(Delimiter);
6267

68+
switch(CountExceedingBehaviour)
69+
{
70+
case CountExceedingBehaviour.CutLastElements:
71+
break;
72+
case CountExceedingBehaviour.AppendLastElements:
73+
if(currentCount == CountMinusOne)
74+
{
75+
ReadOnlySpan<char> lower = span[..index];
76+
ReadOnlySpan<char> upper = span[(index + Delimiter.Length)..];
77+
Span<char> temp = new char[lower.Length + upper.Length];
78+
lower.CopyTo(temp[..index]);
79+
upper.CopyTo(temp[(index + Delimiter.Length - 1)..]);
80+
Current = temp;
81+
currentCount++;
82+
return true;
83+
}
84+
break;
85+
default:
86+
throw new InvalidCountExceedingBehaviourException(CountExceedingBehaviour);
87+
}
6388
if(index == -1 || index >= span.Length)
6489
{
6590
Span = ReadOnlySpan<char>.Empty;

src/Enumerators/SplitSequence/SpanSplitSequenceWithCountEnumerator.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,31 @@ namespace SpanExtensions.Enumerators
1111
ReadOnlySpan<T> Span;
1212
readonly ReadOnlySpan<T> Delimiter;
1313
readonly int Count;
14+
readonly CountExceedingBehaviour CountExceedingBehaviour;
1415
int currentCount;
16+
readonly int CountMinusOne;
1517

1618
/// <summary>
1719
/// Gets the element in the collection at the current position of the enumerator.
1820
/// </summary>
1921
public ReadOnlySpan<T> Current { get; internal set; }
2022

2123
/// <summary>
22-
/// Constructs a <see cref="SpanSplitSequenceWithCountEnumerator{T}"/> from a span and a delimiter. <strong>Only consume this class through <see cref="ReadOnlySpanExtensions.Split{T}(ReadOnlySpan{T}, ReadOnlySpan{T}, int)"/></strong>.
24+
/// Constructs a <see cref="SpanSplitSequenceWithCountEnumerator{T}"/> from a span and a delimiter. <strong>Only consume this class through <see cref="ReadOnlySpanExtensions.Split{T}(ReadOnlySpan{T}, ReadOnlySpan{T}, int, CountExceedingBehaviour)"/></strong>.
2325
/// </summary>
2426
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to be split.</param>
2527
/// <param name="delimiter">An instance of <see cref="ReadOnlySpan{T}"/> that delimits the various sub-ReadOnlySpans in <paramref name="source"/>.</param>
2628
/// <param name="count">The maximum number of sub-ReadOnlySpans to split into.</param>
27-
public SpanSplitSequenceWithCountEnumerator(ReadOnlySpan<T> source, ReadOnlySpan<T> delimiter, int count)
29+
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
30+
public SpanSplitSequenceWithCountEnumerator(ReadOnlySpan<T> source, ReadOnlySpan<T> delimiter, int count, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.CutLastElements)
2831
{
2932
Span = source;
3033
Delimiter = delimiter;
3134
Count = count;
35+
CountExceedingBehaviour = countExceedingBehaviour;
3236
Current = default;
3337
currentCount = 0;
38+
CountMinusOne = Math.Max(Count - 1, 0);
3439
}
3540

3641
/// <summary>
@@ -57,6 +62,26 @@ public bool MoveNext()
5762
return false;
5863
}
5964
int index = span.IndexOf(Delimiter);
65+
switch(CountExceedingBehaviour)
66+
{
67+
case CountExceedingBehaviour.CutLastElements:
68+
break;
69+
case CountExceedingBehaviour.AppendLastElements:
70+
if(currentCount == CountMinusOne)
71+
{
72+
ReadOnlySpan<T> lower = span[..index];
73+
ReadOnlySpan<T> upper = span[(index + Delimiter.Length)..];
74+
Span<T> temp = new T[lower.Length + upper.Length];
75+
lower.CopyTo(temp[..index]);
76+
upper.CopyTo(temp[(index + Delimiter.Length - 1)..]);
77+
Current = temp;
78+
currentCount++;
79+
return true;
80+
}
81+
break;
82+
default:
83+
throw new InvalidCountExceedingBehaviourException(CountExceedingBehaviour);
84+
}
6085
if(index == -1 || index >= span.Length)
6186
{
6287
Span = ReadOnlySpan<T>.Empty;

0 commit comments

Comments
 (0)