Skip to content

Commit d9bd5c5

Browse files
authored
Merge pull request #20 from draconware-dev/dev
Version 1.3.0
2 parents 82eb71b + d63189b commit d9bd5c5

File tree

80 files changed

+5928
-1502
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+5928
-1502
lines changed

.editorconfig

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
# IDE0090: Use 'new(...)'
44
csharp_style_implicit_object_creation_when_type_is_apparent = false:silent
5-
csharp_using_directive_placement = outside_namespace:suggestion
5+
csharp_using_directive_placement = outside_namespace:warning
66
csharp_prefer_simple_using_statement = true:suggestion
77
csharp_prefer_braces = true:suggestion
8-
csharp_style_namespace_declarations = block_scoped:suggestion
8+
csharp_style_namespace_declarations = block_scoped:error
99
csharp_style_prefer_method_group_conversion = true:silent
10-
csharp_style_prefer_top_level_statements = true:silent
10+
csharp_style_prefer_top_level_statements = true:suggestion
1111
csharp_style_expression_bodied_methods = false:silent
1212
csharp_style_expression_bodied_constructors = false:silent
1313
csharp_style_expression_bodied_operators = false:silent
@@ -50,6 +50,15 @@ csharp_style_var_when_type_is_apparent = true:suggestion
5050
csharp_style_var_elsewhere = false:suggestion
5151
dotnet_diagnostic.CA1001.severity = warning
5252
dotnet_diagnostic.CA1309.severity = warning
53+
dotnet_diagnostic.CA1510.severity = none
54+
csharp_style_prefer_primary_constructors = false:error
55+
dotnet_diagnostic.CA1311.severity = warning
56+
dotnet_diagnostic.SYSLIB1054.severity = warning
57+
dotnet_diagnostic.CA1805.severity = suggestion
58+
dotnet_diagnostic.CA1825.severity = suggestion
59+
dotnet_diagnostic.CA1824.severity = warning
60+
dotnet_diagnostic.CA1870.severity = warning
61+
csharp_style_prefer_readonly_struct_member = true:suggestion
5362

5463
[*.{cs,vb}]
5564
#### Naming styles ####
@@ -105,14 +114,14 @@ dotnet_style_prefer_auto_properties = true:silent
105114
dotnet_style_object_initializer = true:suggestion
106115
dotnet_style_collection_initializer = true:suggestion
107116
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
108-
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
109-
dotnet_style_prefer_conditional_expression_over_return = true:silent
117+
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
118+
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
110119
dotnet_style_operator_placement_when_wrapping = beginning_of_line
111120
tab_width = 4
112121
indent_size = 4
113122
end_of_line = crlf
114123
dotnet_style_allow_multiple_blank_lines_experimental = false:suggestion
115-
dotnet_style_prefer_collection_expression = false
124+
dotnet_style_prefer_collection_expression = never:silent
116125
csharp_style_prefer_primary_constructors = false
117126
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
118127
dotnet_style_explicit_tuple_names = true:suggestion
@@ -139,6 +148,14 @@ dotnet_diagnostic.CA1000.severity = silent
139148
dotnet_diagnostic.CA1304.severity = warning
140149
dotnet_diagnostic.CA1305.severity = warning
141150
dotnet_diagnostic.CA1310.severity = warning
151+
dotnet_diagnostic.CA2101.severity = warning
152+
dotnet_diagnostic.CA1401.severity = warning
153+
dotnet_diagnostic.CA1511.severity = none
154+
dotnet_diagnostic.CA1512.severity = none
155+
dotnet_diagnostic.CA1806.severity = suggestion
156+
dotnet_diagnostic.CA1821.severity = warning
157+
dotnet_diagnostic.CA1826.severity = warning
158+
dotnet_diagnostic.CA1829.severity = warning
142159

143160
[*.vb]
144161
dotnet_diagnostic.CA1047.severity = suggestion

.github/README.md

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# SpanExtensions
22

3+
[![NuGet Badge](https://buildstats.info/nuget/SpanExtensions.Net)](https://www.nuget.org/packages/SpanExtensions.Net)
4+
35
## About
46
**`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.
57

@@ -9,8 +11,6 @@ Never again switch back to using `string` instead of `ReadonlySpan<T>`, just bec
911

1012
**SpanExtensions.Net** provides alternatives for many missing Extension Methods for **`ReadonlySpan<T>`** and **`Span<T>`**, ranging from `string.Split()` over `Enumerable.Skip()` and `Enumerable.Take()` to an improved `ReadOnlySpan<T>.IndexOf()`.
1113

12-
**SpanExtensions.Net** may also be found on [NuGet](https://www.nuget.org/packages/SpanExtensions.Net).
13-
1414
## Methods
1515
The following **Extension Methods** are contained:
1616

@@ -43,6 +43,38 @@ The following **Extension Methods** are contained:
4343
- `(ReadOnly-)Span<T>.Takelast(int count)`
4444
- `(ReadOnly-)Span<T>.SkipWhile(Predicate<T> condition)`
4545
- `(ReadOnly-)Span<T>.TakeWhile(Predicate<T> condition)`
46+
- `(Readonly-)Span<T>.First()`
47+
- `(Readonly-)Span<T>.First(Predicate<T> predicate)`
48+
- `(Readonly-)Span<T>.FirstOrDefault()`
49+
- `(Readonly-)Span<T>.FirstOrDefault(Predicate<T> predicate)`
50+
- `(Readonly-)Span<T>.FirstOrDefault(T defaultValue)`
51+
- `(Readonly-)Span<T>.FirstOrDefault(Predicate<T> predicate, T defaultValue)`
52+
- `(Readonly-)Span<T>.Last()`
53+
- `(Readonly-)Span<T>.Last(Predicate<T> predicate)`
54+
- `(Readonly-)Span<T>.LastOrDefault()`
55+
- `(Readonly-)Span<T>.LastOrDefault(Predicate<T> predicate)`
56+
- `(Readonly-)Span<T>.LastOrDefault(T defaultValue)`
57+
- `(Readonly-)Span<T>.LastOrDefault(Predicate<T> predicate, T defaultValue)`
58+
- `(Readonly-)Span<T>.Single()`
59+
- `(Readonly-)Span<T>.Single(Predicate<T> predicate)`
60+
- `(Readonly-)Span<T>.SingleOrDefault()`
61+
- `(Readonly-)Span<T>.SingleOrDefault(Predicate<T> predicate)`
62+
- `(Readonly-)Span<T>.SingleOrDefault(T defaultValue)`
63+
- `(Readonly-)Span<T>.SingleOrDefault(Predicate<T> predicate, T defaultValue)`
64+
- `(Readonly-)Span<T>.ElementAt(int index)`
65+
- `(Readonly-)Span<T>.ElementAt(Index index)`
66+
- `(Readonly-)Span<T>.ElementAtOrDefault(int index)`
67+
- `(Readonly-)Span<T>.ElementAtOrDefault(Index index)`
68+
- `(Readonly-)Span<T>.ElementAtOrDefault(int index, T defaultValue)`
69+
- `(Readonly-)Span<T>.ElementAtOrDefault(Index index, T defaultValue)`
70+
- `(Readonly-)Span<T>.Min()`
71+
- `(Readonly-)Span<T>.Min(Func<TSource, TResult> selector)`
72+
- `(Readonly-)Span<T>.MinBy(Func<TSource, TKey> keySelector)`
73+
- `(Readonly-)Span<T>.MinBy(Func<TSource, TKey> keySelector, IComparer<TKey> comparer)`
74+
- `(Readonly-)Span<T>.Max()`
75+
- `(Readonly-)Span<T>.Max(Func<TSource, TResult> selector)`
76+
- `(Readonly-)Span<T>.MaxBy(Func<TSource, TKey> keySelector)`
77+
- `(Readonly-)Span<T>.MaxBy(Func<TSource, TKey> keySelector, IComparer<TKey> comparer)`
4678

4779
## Contributing
4880

@@ -51,4 +83,4 @@ Thank you for your interest in contributing to this project - Please see [Contri
5183

5284
Copyright (c) draconware-dev. All rights reserved.
5385

54-
Licensed under the [MIT](../LICENSE) license.
86+
Licensed under the [MIT](../LICENSE) License.

.github/workflows/dotnet.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
name: .NET
3+
4+
on:
5+
push:
6+
branches: [ "main" ]
7+
pull_request:
8+
branches: [ "dev" ]
9+
paths:
10+
- '**.cs'
11+
- '**.csproj'
12+
13+
jobs:
14+
build:
15+
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- uses: actions/checkout@v3
20+
- name: Setup .NET
21+
uses: actions/setup-dotnet@v3
22+
with:
23+
dotnet-version: 8.0.x
24+
- name: Restore dependencies
25+
run: dotnet restore
26+
- name: Build
27+
run: dotnet build --no-restore
28+
- name: Test
29+
run: dotnet test --no-build --verbosity normal

Changelog.md

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,63 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.3] - 2024-3-19
9+
10+
### Added
11+
12+
- Compatibility with **.Net 8**
13+
- `(Readonly-)Span<T>.First()`
14+
- `(Readonly-)Span<T>.First(Predicate<T> predicate)`
15+
- `(Readonly-)Span<T>.FirstOrDefault()`
16+
- `(Readonly-)Span<T>.FirstOrDefault(Predicate<T> predicate)`
17+
- `(Readonly-)Span<T>.FirstOrDefault(T defaultValue)`
18+
- `(Readonly-)Span<T>.FirstOrDefault(Predicate<T> predicate, T defaultValue)`
19+
- `(Readonly-)Span<T>.Last()`
20+
- `(Readonly-)Span<T>.Last(Predicate<T> predicate)`
21+
- `(Readonly-)Span<T>.LastOrDefault()`
22+
- `(Readonly-)Span<T>.LastOrDefault(Predicate<T> predicate)`
23+
- `(Readonly-)Span<T>.LastOrDefault(T defaultValue)`
24+
- `(Readonly-)Span<T>.LastOrDefault(Predicate<T> predicate, T defaultValue)`
25+
- `(Readonly-)Span<T>.Single()`
26+
- `(Readonly-)Span<T>.Single(Predicate<T> predicate)`
27+
- `(Readonly-)Span<T>.SingleOrDefault()`
28+
- `(Readonly-)Span<T>.SingleOrDefault(Predicate<T> predicate)`
29+
- `(Readonly-)Span<T>.SingleOrDefault(T defaultValue)`
30+
- `(Readonly-)Span<T>.SingleOrDefault(Predicate<T> predicate, T defaultValue)`
31+
- `(Readonly-)Span<T>.ElementAt(int index)`
32+
- `(Readonly-)Span<T>.ElementAt(Index index)`
33+
- `(Readonly-)Span<T>.ElementAtOrDefault(int index)`
34+
- `(Readonly-)Span<T>.ElementAtOrDefault(Index index)`
35+
- `(Readonly-)Span<T>.ElementAtOrDefault(int index, T defaultValue)`
36+
- `(Readonly-)Span<T>.ElementAtOrDefault(Index index, T defaultValue)`
37+
- `(Readonly-)Span<T>.Min()` (https://github.com/draconware-dev/SpanExtensions.Net/pull/13)
38+
- `(Readonly-)Span<T>.Min(Func<TSource, TResult> selector)`
39+
- `(Readonly-)Span<T>.MinBy(Func<TSource, TKey> keySelector)`
40+
- `(Readonly-)Span<T>.MinBy(Func<TSource, TKey> keySelector, IComparer<TKey> comparer)`
41+
- `(Readonly-)Span<T>.Max()` (https://github.com/draconware-dev/SpanExtensions.Net/pull/13)
42+
- `(Readonly-)Span<T>.Max(Func<TSource, TResult> selector)`
43+
- `(Readonly-)Span<T>.MaxBy(Func<TSource, TKey> keySelector)`
44+
- `(Readonly-)Span<T>.MaxBy(Func<TSource, TKey> keySelector, IComparer<TKey> comparer)`
45+
- nuget badge to README (https://github.com/draconware-dev/SpanExtensions.Net/pull/12)
46+
- `CountExceedingBehaviour`, which is passed to Split, defining how to properly handle its remaining elements.
47+
48+
### Changed
49+
50+
- documentation comments to better reflect the dotnet style (https://github.com/draconware-dev/SpanExtensions.Net/pull/8)
51+
- swapped order of `count` and `stringSplitOptions arguments` in `Split` methods.
52+
- renamed argument `span` in `Split` methods to `source`.
53+
54+
### Fixed
55+
56+
- empty spans being ignored if they are the last element to be returned from `Split` and are therefore not returned. (https://github.com/draconware-dev/SpanExtensions.Net/pull/10)
57+
858
## [1.2.1] - 2024-1-25
959

1060
### Fixed
1161

1262
- Ambiguous Extension Methods (https://github.com/draconware-dev/SpanExtensions.Net/issues/6)
1363
- Correctness of some documentation comments
1464

15-
### Changed
16-
17-
- moved custom Enumerators into `SpanExtensions.Enumerators`
18-
- declared every `GetEnumerator` method in a ref struct as `readonly`
19-
2065
## [1.2.0] - 2023-12-28
2166

2267
### Added

src/CountExceedingBehaviour.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace SpanExtensions
2+
{
3+
/// <summary>
4+
/// Defines the behaviour of a split operation when there are more split instances than there may be.
5+
/// </summary>
6+
public enum CountExceedingBehaviour
7+
{
8+
/// <summary>
9+
/// The last element returned will be all the remaining elements appended as one.
10+
/// </summary>
11+
AppendRemainingElements,
12+
/// <summary>
13+
/// Every split instance more than permitted will not be returned.
14+
/// </summary>
15+
CutRemainingElements
16+
}
17+
}

src/Enumerators/Split/SpanSplitEnumerator.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,34 @@ namespace SpanExtensions.Enumerators
55
/// <summary>
66
/// Supports iteration over a <see cref="ReadOnlySpan{T}"/> by splitting it at a specified delimiter of type <typeparamref name="T"/>.
77
/// </summary>
8-
/// <typeparam name="T">The type of elements in the enumerated <see cref="ReadOnlySpan{T}"/></typeparam>
8+
/// <typeparam name="T">The type of elements in the enumerated <see cref="ReadOnlySpan{T}"/>.</typeparam>
99
public ref struct SpanSplitEnumerator<T> where T : IEquatable<T>
1010
{
1111
ReadOnlySpan<T> Span;
1212
readonly T Delimiter;
13+
bool enumerationDone;
1314

1415
/// <summary>
15-
/// Gets the element in the collection at the current position of the enumerator.
16+
/// Gets the element in the collection at the current position of the enumerator.
1617
/// </summary>
1718
public ReadOnlySpan<T> Current { get; internal set; }
1819

1920
/// <summary>
20-
/// Constructs a <see cref="SpanSplitEnumerator{T}"/> from a span and a delimiter. ONLY CONSUME THIS CLASS THROUGH <see cref="ReadOnlySpanExtensions.Split{T}(ReadOnlySpan{T}, T)"/>.
21+
/// Constructs a <see cref="SpanSplitEnumerator{T}"/> from a span and a delimiter. <strong>Only consume this class through <see cref="ReadOnlySpanExtensions.Split{T}(ReadOnlySpan{T}, T)"/></strong>.
2122
/// </summary>
22-
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to be split.</param>
23-
/// <param name="delimiter">An instance of <typeparamref name="T"/> that delimits the various sub-ReadOnlySpans in the <see cref="ReadOnlySpan{T}"/>.</param>
23+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to be split.</param>
24+
/// <param name="delimiter">An instance of <typeparamref name="T"/> that delimits the various sub-ReadOnlySpans in <paramref name="source"/>.</param>
2425
public SpanSplitEnumerator(ReadOnlySpan<T> source, T delimiter)
2526
{
2627
Span = source;
2728
Delimiter = delimiter;
2829
Current = default;
30+
enumerationDone = false;
2931
}
30-
/// <summary></summary>
32+
33+
/// <summary>
34+
/// Returns an enumerator that iterates through a collection.
35+
/// </summary>
3136
public readonly SpanSplitEnumerator<T> GetEnumerator()
3237
{
3338
return this;
@@ -36,19 +41,20 @@ public readonly SpanSplitEnumerator<T> GetEnumerator()
3641
/// <summary>
3742
/// Advances the enumerator to the next element of the collection.
3843
/// </summary>
39-
/// <returns><code>true</code> if the enumerator was successfully advanced to the next element; <code>false</code> if the enumerator has passed the end of the collection.</returns>
44+
/// <returns><see langword="true"/> if the enumerator was successfully advanced to the next element; <see langword="false"/> if the enumerator has passed the end of the collection.</returns>
4045
public bool MoveNext()
4146
{
42-
ReadOnlySpan<T> span = Span;
43-
if(span.IsEmpty)
47+
if(enumerationDone)
4448
{
4549
return false;
4650
}
51+
52+
ReadOnlySpan<T> span = Span;
4753
int index = span.IndexOf(Delimiter);
4854

4955
if(index == -1 || index >= span.Length)
5056
{
51-
Span = ReadOnlySpan<T>.Empty;
57+
enumerationDone = true;
5258
Current = span;
5359
return true;
5460
}

0 commit comments

Comments
 (0)