Skip to content

Commit 5f8daa1

Browse files
committed
add
1 parent 6b31822 commit 5f8daa1

9 files changed

+58
-123
lines changed

src/CountExceedingBehaviour.cs

Lines changed: 3 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
using System;
2-
using System.Globalization;
3-
4-
namespace SpanExtensions
1+
namespace SpanExtensions
52
{
63
/// <summary>
7-
/// Defines the behaviour of a split operation when there are more split instances than desired.
4+
/// Defines the behaviour of a split operation when there are more split instances than there may be.
85
/// </summary>
96
public enum CountExceedingBehaviour
107
{
@@ -17,62 +14,4 @@ public enum CountExceedingBehaviour
1714
/// </summary>
1815
CutRemainingElements
1916
}
20-
21-
/// <summary>
22-
/// Extension methods for <see cref="CountExceedingBehaviour"/>.
23-
/// </summary>
24-
static class CountExceedingBehaviourExtensions
25-
{
26-
static string? CountExceedingBehaviourInvalidFormat;
27-
28-
/// <summary>
29-
/// Validates whether a specified value is a valid <see cref="CountExceedingBehaviour"/>.
30-
/// </summary>
31-
/// <param name="countExceedingBehaviour">The <see cref="CountExceedingBehaviour"/> to validate.</param>
32-
/// <returns>The specified <see cref="CountExceedingBehaviour"/> if valid.</returns>
33-
/// <exception cref="ArgumentException">If <paramref name="countExceedingBehaviour"/> is not valid.</exception>
34-
public static CountExceedingBehaviour ThrowIfInvalid(this CountExceedingBehaviour countExceedingBehaviour)
35-
{
36-
#if NET5_0_OR_GREATER
37-
if(!Enum.IsDefined(countExceedingBehaviour))
38-
#else
39-
if(!Enum.IsDefined(typeof(CountExceedingBehaviour), countExceedingBehaviour))
40-
#endif
41-
{
42-
if(CountExceedingBehaviourInvalidFormat == null)
43-
{
44-
#if NET5_0_OR_GREATER
45-
string[] names = Enum.GetNames<CountExceedingBehaviour>();
46-
#else
47-
string[] names = Enum.GetNames(typeof(CountExceedingBehaviour));
48-
#endif
49-
CountExceedingBehaviourInvalidFormat = $"{nameof(CountExceedingBehaviour)} doesn't define an option with the value '{{0}}'. Valid values are {string.Join(", ", names)}.";
50-
}
51-
52-
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, CountExceedingBehaviourInvalidFormat, (int)countExceedingBehaviour), nameof(countExceedingBehaviour));
53-
}
54-
55-
return countExceedingBehaviour;
56-
}
57-
58-
/// <summary>
59-
/// Determines whether the current instance is <see cref="CountExceedingBehaviour.AppendRemainingElements"/>.
60-
/// </summary>
61-
/// <param name="countExceedingBehaviour">The <see cref="CountExceedingBehaviour"/> instance to test.</param>
62-
/// <returns><see langword="true"/> if <paramref name="countExceedingBehaviour"/> is <see cref="CountExceedingBehaviour.AppendRemainingElements"/>; <see langword="false"/> otherwise.</returns>
63-
public static bool IsAppendRemainingElements(this CountExceedingBehaviour countExceedingBehaviour)
64-
{
65-
return countExceedingBehaviour == CountExceedingBehaviour.AppendRemainingElements;
66-
}
67-
68-
/// <summary>
69-
/// Determines whether the current instance is <see cref="CountExceedingBehaviour.CutRemainingElements"/>.
70-
/// </summary>
71-
/// <param name="countExceedingBehaviour">The <see cref="CountExceedingBehaviour"/> instance to test.</param>
72-
/// <returns><see langword="true"/> if <paramref name="countExceedingBehaviour"/> is <see cref="CountExceedingBehaviour.CutRemainingElements"/>; <see langword="false"/> otherwise.</returns>
73-
public static bool IsCutRemainingElements(this CountExceedingBehaviour countExceedingBehaviour)
74-
{
75-
return countExceedingBehaviour == CountExceedingBehaviour.CutRemainingElements;
76-
}
77-
}
78-
}
17+
}

src/Enumerators/Split/SpanSplitStringSplitOptionsWithCountEnumerator.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ public ref struct SpanSplitStringSplitOptionsWithCountEnumerator
3131
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
3232
public SpanSplitStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, char delimiter, int count, StringSplitOptions options, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.AppendRemainingElements)
3333
{
34+
ExceptionHelpers.ThrowIfNegative(count, nameof(count));
35+
ExceptionHelpers.ThrowIfInvalid(countExceedingBehaviour, nameof(countExceedingBehaviour));
3436
Span = source;
3537
Delimiter = delimiter;
36-
CurrentCount = count.ThrowIfNegative();
38+
CurrentCount = count;
3739
TrimEntries = options.ThrowIfInvalid().IsTrimEntriesSet();
3840
RemoveEmptyEntries = options.IsRemoveEmptyEntriesSet();
39-
CountExceedingBehaviour = countExceedingBehaviour.ThrowIfInvalid();
41+
CountExceedingBehaviour = countExceedingBehaviour;
4042
EnumerationDone = count == 0;
4143
Current = default;
4244

@@ -87,7 +89,7 @@ public bool MoveNext()
8789
continue;
8890
}
8991

90-
if(CountExceedingBehaviour.IsCutRemainingElements())
92+
if(CountExceedingBehaviour == CountExceedingBehaviour.CutRemainingElements)
9193
{
9294
Span = beforeDelimiter;
9395
}
@@ -99,7 +101,7 @@ public bool MoveNext()
99101
}
100102
else
101103
{
102-
Current = delimiterIndex == -1 || CountExceedingBehaviour.IsAppendRemainingElements() ? Span : Span[..delimiterIndex];
104+
Current = delimiterIndex == -1 || CountExceedingBehaviour == CountExceedingBehaviour.AppendRemainingElements ? Span : Span[..delimiterIndex];
103105
}
104106

105107
if(TrimEntries)

src/Enumerators/Split/SpanSplitWithCountEnumerator.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ namespace SpanExtensions.Enumerators
2929
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
3030
public SpanSplitWithCountEnumerator(ReadOnlySpan<T> source, T delimiter, int count, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.AppendRemainingElements)
3131
{
32+
ExceptionHelpers.ThrowIfNegative(count, nameof(count));
3233
Span = source;
3334
Delimiter = delimiter;
34-
CurrentCount = count.ThrowIfNegative();
35+
CurrentCount = count;
3536
CountExceedingBehaviour = countExceedingBehaviour.ThrowIfInvalid();
3637
EnumerationDone = count == 0;
3738
Current = default;
@@ -62,7 +63,7 @@ public bool MoveNext()
6263
{
6364
EnumerationDone = true;
6465

65-
Current = delimiterIndex == -1 || CountExceedingBehaviour.IsAppendRemainingElements() ? Span : Span[..delimiterIndex];
66+
Current = delimiterIndex == -1 || CountExceedingBehaviour == CountExceedingBehaviour.AppendRemainingElements ? Span : Span[..delimiterIndex];
6667

6768
return true;
6869
}

src/Enumerators/SplitAny/SpanSplitAnyStringSplitOptionsWithCountEnumerator.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ public ref struct SpanSplitAnyStringSplitOptionsWithCountEnumerator
3131
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
3232
public SpanSplitAnyStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, ReadOnlySpan<char> delimiters, int count, StringSplitOptions options, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.AppendRemainingElements)
3333
{
34+
ExceptionHelpers.ThrowIfNegative(count, nameof(count));
35+
ExceptionHelpers.ThrowIfInvalid(countExceedingBehaviour, nameof(countExceedingBehaviour));
3436
Span = source;
3537
Delimiters = delimiters;
36-
CurrentCount = count.ThrowIfNegative();
38+
CurrentCount = count;
3739
TrimEntries = options.ThrowIfInvalid().IsTrimEntriesSet();
3840
RemoveEmptyEntries = options.IsRemoveEmptyEntriesSet();
39-
CountExceedingBehaviour = countExceedingBehaviour.ThrowIfInvalid();
41+
CountExceedingBehaviour = countExceedingBehaviour;
4042
EnumerationDone = count == 0;
4143
Current = default;
4244

@@ -87,7 +89,7 @@ public bool MoveNext()
8789
continue;
8890
}
8991

90-
if(CountExceedingBehaviour.IsCutRemainingElements())
92+
if(CountExceedingBehaviour == CountExceedingBehaviour.CutRemainingElements)
9193
{
9294
Span = beforeDelimiter;
9395
}
@@ -99,7 +101,7 @@ public bool MoveNext()
99101
}
100102
else
101103
{
102-
Current = delimiterIndex == -1 || CountExceedingBehaviour.IsAppendRemainingElements() ? Span : Span[..delimiterIndex];
104+
Current = delimiterIndex == -1 || CountExceedingBehaviour == CountExceedingBehaviour.AppendRemainingElements ? Span : Span[..delimiterIndex];
103105
}
104106

105107
if(TrimEntries)

src/Enumerators/SplitAny/SpanSplitAnyWithCountEnumerator.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ namespace SpanExtensions.Enumerators
2929
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
3030
public SpanSplitAnyWithCountEnumerator(ReadOnlySpan<T> source, ReadOnlySpan<T> delimiters, int count, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.AppendRemainingElements)
3131
{
32+
ExceptionHelpers.ThrowIfNegative(count, nameof(count));
33+
ExceptionHelpers.ThrowIfInvalid(countExceedingBehaviour, nameof(countExceedingBehaviour));
3234
Span = source;
3335
Delimiters = delimiters;
34-
CurrentCount = count.ThrowIfNegative();
35-
CountExceedingBehaviour = countExceedingBehaviour.ThrowIfInvalid();
36+
CurrentCount = count;
37+
CountExceedingBehaviour = countExceedingBehaviour;
3638
EnumerationDone = count == 0;
3739
Current = default;
3840
}
@@ -62,7 +64,7 @@ public bool MoveNext()
6264
{
6365
EnumerationDone = true;
6466

65-
Current = delimiterIndex == -1 || CountExceedingBehaviour.IsAppendRemainingElements() ? Span : Span[..delimiterIndex];
67+
Current = delimiterIndex == -1 || CountExceedingBehaviour == CountExceedingBehaviour.AppendRemainingElements ? Span : Span[..delimiterIndex];
6668

6769
return true;
6870
}

src/Enumerators/SplitSequence/SpanSplitSequenceStringSplitOptionsWithCountEnumerator.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,16 @@ public ref struct SpanSplitSequenceStringSplitOptionsWithCountEnumerator
3232
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
3333
public SpanSplitSequenceStringSplitOptionsWithCountEnumerator(ReadOnlySpan<char> source, ReadOnlySpan<char> delimiter, int count, StringSplitOptions options, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.AppendRemainingElements)
3434
{
35+
ExceptionHelpers.ThrowIfNegative(count, nameof(count));
36+
ExceptionHelpers.ThrowIfInvalid(countExceedingBehaviour, nameof(countExceedingBehaviour));
3537
Span = source;
3638
Delimiter = delimiter;
3739
DelimiterLength = Delimiter.Length;
3840
DelimiterIsEmpty = Delimiter.IsEmpty;
39-
CurrentCount = DelimiterIsEmpty ? 0 : count.ThrowIfNegative();
41+
CurrentCount = DelimiterIsEmpty ? 0 : count;
4042
TrimEntries = options.ThrowIfInvalid().IsTrimEntriesSet();
4143
RemoveEmptyEntries = options.IsRemoveEmptyEntriesSet();
42-
CountExceedingBehaviour = countExceedingBehaviour.ThrowIfInvalid();
44+
CountExceedingBehaviour = countExceedingBehaviour;
4345
EnumerationDone = count == 0;
4446
Current = default;
4547

@@ -90,7 +92,7 @@ public bool MoveNext()
9092
continue;
9193
}
9294

93-
if(CountExceedingBehaviour.IsCutRemainingElements())
95+
if(CountExceedingBehaviour == CountExceedingBehaviour.CutRemainingElements)
9496
{
9597
Span = beforeDelimiter;
9698
}
@@ -102,7 +104,7 @@ public bool MoveNext()
102104
}
103105
else
104106
{
105-
Current = delimiterIndex == -1 || CountExceedingBehaviour.IsAppendRemainingElements() || DelimiterIsEmpty ? Span : Span[..delimiterIndex];
107+
Current = delimiterIndex == -1 || CountExceedingBehaviour == CountExceedingBehaviour.AppendRemainingElements || DelimiterIsEmpty ? Span : Span[..delimiterIndex];
106108
}
107109

108110
if(TrimEntries)

src/Enumerators/SplitSequence/SpanSplitSequenceWithCountEnumerator.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ namespace SpanExtensions.Enumerators
3030
/// <param name="countExceedingBehaviour">The handling of the instances more than count.</param>
3131
public SpanSplitSequenceWithCountEnumerator(ReadOnlySpan<T> source, ReadOnlySpan<T> delimiter, int count, CountExceedingBehaviour countExceedingBehaviour = CountExceedingBehaviour.AppendRemainingElements)
3232
{
33+
ExceptionHelpers.ThrowIfNegative(count, nameof(count));
34+
ExceptionHelpers.ThrowIfInvalid(countExceedingBehaviour, nameof(countExceedingBehaviour));
3335
Span = source;
3436
Delimiter = delimiter;
3537
DelimiterLength = Delimiter.Length;
3638
DelimiterIsEmpty = Delimiter.IsEmpty;
37-
CurrentCount = DelimiterIsEmpty ? 1 : count.ThrowIfNegative();
38-
CountExceedingBehaviour = countExceedingBehaviour.ThrowIfInvalid();
39+
CurrentCount = DelimiterIsEmpty ? 1 : count;
40+
CountExceedingBehaviour = countExceedingBehaviour;
3941
EnumerationDone = count == 0;
4042
Current = default;
4143
}
@@ -65,7 +67,7 @@ public bool MoveNext()
6567
{
6668
EnumerationDone = true;
6769

68-
Current = delimiterIndex == -1 || CountExceedingBehaviour.IsAppendRemainingElements() || DelimiterIsEmpty ? Span : Span[..delimiterIndex];
70+
Current = delimiterIndex == -1 || CountExceedingBehaviour == CountExceedingBehaviour.AppendRemainingElements || DelimiterIsEmpty ? Span : Span[..delimiterIndex];
6971

7072
return true;
7173
}

src/ExceptionHelpers.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
22
using System.Diagnostics.CodeAnalysis;
3+
using System.Globalization;
34
using System.Numerics;
45
using System.Runtime.CompilerServices;
6+
using SpanExtensions;
57

68
static class ExceptionHelpers
79
{
@@ -28,6 +30,27 @@ internal static void ThrowIfLessThan<T>(T value, T other,
2830
}
2931
}
3032

33+
internal static void ThrowIfInvalid(CountExceedingBehaviour countExceedingBehaviour,
34+
#if NET8_0_OR_GREATER
35+
[CallerArgumentExpression(nameof(countExceedingBehaviour))]
36+
#endif
37+
string? paramName = null)
38+
{
39+
#if NET5_0_OR_GREATER
40+
if(!Enum.IsDefined(countExceedingBehaviour))
41+
#else
42+
if(!Enum.IsDefined(typeof(CountExceedingBehaviour), countExceedingBehaviour))
43+
#endif
44+
{
45+
#if NET5_0_OR_GREATER
46+
string[] names = Enum.GetNames<CountExceedingBehaviour>();
47+
#else
48+
string[] names = Enum.GetNames(typeof(CountExceedingBehaviour));
49+
#endif
50+
throw new ArgumentException($"{nameof(CountExceedingBehaviour)} does not define an option with the value '{countExceedingBehaviour}'. Valid options are {string.Join(", ", names)}.", nameof(countExceedingBehaviour));
51+
}
52+
}
53+
3154
internal static void ThrowIfOutOfBounds<T>(T value, T lowerBound, T upperBound,
3255
#if NET8_0_OR_GREATER
3356
[CallerArgumentExpression(nameof(value))]
@@ -60,6 +83,7 @@ internal static void ThrowIfNegative<T>(T value,
6083
ThrowNegative(value, paramName);
6184
}
6285
}
86+
6387
#else
6488
internal static void ThrowIfOutOfArrayBounds(int value, int upperBound,
6589
#if NET8_0_OR_GREATER

src/InternalExtensions.cs

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,6 @@ namespace SpanExtensions
77
{
88
static class InternalExtensions
99
{
10-
#if NETCOREAPP3_0_OR_GREATER
11-
/// <summary>
12-
/// Throws an <see cref="ArgumentOutOfRangeException"/> if <paramref name="value"/> is negative.
13-
/// </summary>
14-
/// <param name="value">The argument to validate as non-negative.</param>
15-
/// <param name="paramName">The name of the parameter with which <paramref name="value"/> corresponds.</param>
16-
/// <returns><paramref name="value"/>.</returns>
17-
public static int ThrowIfNegative(this int value, [CallerArgumentExpression(nameof(value))] string? paramName = null)
18-
{
19-
#if NET8_0_OR_GREATER
20-
ArgumentOutOfRangeException.ThrowIfNegative(value, paramName);
21-
#else
22-
if(value < 0)
23-
{
24-
throw new ArgumentOutOfRangeException(paramName, value, $"{paramName} ('{value}') must be a non-negative value.");
25-
}
26-
#endif
27-
28-
return value;
29-
}
30-
#else
31-
/// <summary>
32-
/// Throws an <see cref="ArgumentOutOfRangeException"/> if <paramref name="value"/> is negative.
33-
/// </summary>
34-
/// <param name="value">The argument to validate as non-negative.</param>
35-
/// <returns><paramref name="value"/>.</returns>
36-
public static int ThrowIfNegative(this int value)
37-
{
38-
if(value < 0)
39-
{
40-
#pragma warning disable S3928 // Parameter names used into ArgumentException constructors should match an existing one
41-
throw new ArgumentOutOfRangeException(null, value, $" ('{value}') must be a non-negative value.");
42-
#pragma warning restore S3928 // Parameter names used into ArgumentException constructors should match an existing one
43-
}
44-
45-
return value;
46-
}
47-
#endif
48-
4910
#if NETCOREAPP3_0_OR_GREATER
5011
/// <summary>
5112
/// Throws an <see cref="ArgumentException"/> if <paramref name="options"/> is not a valid flag.

0 commit comments

Comments
 (0)