Skip to content

Commit 1d3cb1e

Browse files
authored
v2!
Version 2.0.
2 parents 99d8486 + 6df54d4 commit 1d3cb1e

File tree

23 files changed

+2887
-258
lines changed

23 files changed

+2887
-258
lines changed

.github/CONTRIBUTING.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
# Contributing to SpanExtensions.Net
2-
2+
33
### Did you catch a bug?
44

55
**!!!Important!!!**
6-
If the bug poses a threat to the security of dependent applications, please refer to our [Security Policy](SECURITY.md).
6+
If the bug poses a threat to the security of dependent applications, please refer to our [Security Policy](SECURITY.md).
77

88
There are two options available:
99

10-
1. You can open an issue describing exactly:
11-
- What is the bug and what did you expect to happen?
12-
- How may it be reproduced (It is often helpful to include images or alike).
13-
- Include the Version of SpanExtensions.Net affected.
14-
2. Even better, you can fix the issue yourself by submitting a pull reqest.
10+
1. You can open an issue describing exactly:
11+
- What the bug is and what you expected to happen?
12+
- How it may be reproduced (It is often helpful to include images or alike).
13+
- hich versions of SpanExtensions.Net affected.
14+
2. Even better, fix any issue yourself by submitting a pull request.
1515

1616
### Do you have a feature request?
1717

1818
Tell us all about it (here)[]. Please consider however, that features should generally be implementable via Extension Methods, otherwise they are unlikely to be accepted.
1919

20-
### Did you notice a mistake or an error in the documentation?
20+
### Did you notice a mistake or an error in the documentation?
2121

22-
If you found a spelling mistake or an ambigous or unclear sentence or phrase in the XML documentation in C# source files or in any of the documentation for this repository (for example: Readme.md), do one of the following:
22+
If you found a spelling mistake or an ambigous or unclear sentence or phrase in the XML documentation in C# source files or in any of the documentation for this repository (for example: Readme.md), do one of the following:
2323

24-
[Open an **Issue**](https://github.com/draconware-dev/SpanExtensions.Net/issues/new/choose) with the tag `documentation`. It is recommended to follow the [example template](https://github.com/draconware-dev/SpanExtensions.Net/issues/new?assignees=&labels=documentation&projects=&template=documentation-report.md&title=Documentation+Error).
24+
[Open an **Issue**](https://github.com/draconware-dev/SpanExtensions.Net/issues/new/choose) with the tag `documentation`. It is recommended to follow the [example template](https://github.com/draconware-dev/SpanExtensions.Net/issues/new?assignees=&labels=documentation&projects=&template=documentation-report.md&title=Documentation+Error).
2525

2626
**OR**
2727

28-
[Open a **Pull Request**](https://github.com/draconware-dev/SpanExtensions.Net/compare) linked to an **Issue** tagged `documentation`, as grammatical errors are usually easier to fix, than they are to describe. In this case it is not necessary to describe the error in detail, a brief report with reasoning should do, unless it is not evident from the Pull Request, what actually was changed or why it was changed.
28+
[Open a **Pull Request**](https://github.com/draconware-dev/SpanExtensions.Net/compare) linked to an **Issue** tagged `documentation`, as grammatical errors are usually easier to fix, than they are to describe. In this case it is not necessary to describe the error in detail, a brief report with reasoning should do, unless it is not evident from the Pull Request, what actually was changed or why it was changed.

.github/README.md

Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -5,84 +5,17 @@
55
[![GitHub License](https://img.shields.io/github/license/draconware-dev/SpanExtensions.Net)](https://github.com/draconware-dev/SpanExtensions.Net/blob/main/LICENSE)
66

77
## About
8-
**`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.
98

10-
**SpanExtensions.Net** aims to help developers use `ReadonlySpan<T>` and `Span<T>` more **productively**, **efficiently** and **safely** and write overall more **performant** Programs.
11-
12-
Never again switch back to using `string` instead of `ReadonlySpan<T>`, just because the method you seek is not supported.
13-
14-
**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()`.
9+
Never again switch back to using `string` instead of `ReadonlySpan<T>`, just because the method you seek is not supported.
1510

16-
## Methods
17-
The following **Extension Methods** are contained:
18-
19-
#### String Methods made available for **`ReadonlySpan<T>`** and **`Span<T>`**:
20-
21-
- `(ReadOnly-)Span<T>.Split(T delimiter)`
22-
- `(ReadOnly-)Span<T>.Split(T delimiter, int count)`
23-
- `(ReadOnly-)Span<T>.Split(T delimiter, StringSplitOptions options)`
24-
- `(ReadOnly-)Span<T>.Split(T delimiter, StringSplitOptions options, int count)`
25-
- `(ReadOnly-)Span<T>.Split(ReadOnlySpan<T> delimiters)`
26-
- `(ReadOnly-)Span<T>.Split(ReadOnlySpan<T> delimiters, int count)`
27-
- `(ReadOnly-)Span<T>.Split(ReadOnlySpan<T> delimiters, StringSplitOptions options)`
28-
- `(ReadOnly-)Span<T>.Split(ReadOnlySpan<T> delimiters, StringSplitOptions options, int count)`
29-
- `(ReadOnly-)Span<T>.SplitAny(ReadOnlySpan<T> delimiters)`
30-
- `(ReadOnly-)Span<T>.SplitAny(ReadOnlySpan<T> delimiters, int count)`
31-
- `(ReadOnly-)Span<T>.SplitAny(ReadOnlySpan<T> delimiters, StringSplitOptions options)`
32-
- `(ReadOnly-)Span<T>.SplitAny(ReadOnlySpan<T> delimiters, StringSplitOptions options, int count)`
33-
- `(ReadOnly-)Span<T>.Remove(int startIndex)`
34-
- `Span<T>.Replace(T oldT, T newT)`
35-
36-
#### Linq Methods made available for **`ReadonlySpan<T>`** and **`Span<T>`**:
37-
38-
- `(ReadOnly-)Span<T>.All(Predicate<T> predicate)`
39-
- `(ReadOnly-)Span<T>.Any(Predicate<T> predicate)`
40-
- `(ReadOnly-)Span<T>.Average()`
41-
- `(ReadOnly-)Span<T>.Sum()`
42-
- `(ReadOnly-)Span<T>.Skip(int count)`
43-
- `(ReadOnly-)Span<T>.Take(int count)`
44-
- `(ReadOnly-)Span<T>.SkipLast(int count)`
45-
- `(ReadOnly-)Span<T>.Takelast(int count)`
46-
- `(ReadOnly-)Span<T>.SkipWhile(Predicate<T> condition)`
47-
- `(ReadOnly-)Span<T>.TakeWhile(Predicate<T> condition)`
48-
- `(Readonly-)Span<T>.First()`
49-
- `(Readonly-)Span<T>.First(Predicate<T> predicate)`
50-
- `(Readonly-)Span<T>.FirstOrDefault()`
51-
- `(Readonly-)Span<T>.FirstOrDefault(Predicate<T> predicate)`
52-
- `(Readonly-)Span<T>.FirstOrDefault(T defaultValue)`
53-
- `(Readonly-)Span<T>.FirstOrDefault(Predicate<T> predicate, T defaultValue)`
54-
- `(Readonly-)Span<T>.Last()`
55-
- `(Readonly-)Span<T>.Last(Predicate<T> predicate)`
56-
- `(Readonly-)Span<T>.LastOrDefault()`
57-
- `(Readonly-)Span<T>.LastOrDefault(Predicate<T> predicate)`
58-
- `(Readonly-)Span<T>.LastOrDefault(T defaultValue)`
59-
- `(Readonly-)Span<T>.LastOrDefault(Predicate<T> predicate, T defaultValue)`
60-
- `(Readonly-)Span<T>.Single()`
61-
- `(Readonly-)Span<T>.Single(Predicate<T> predicate)`
62-
- `(Readonly-)Span<T>.SingleOrDefault()`
63-
- `(Readonly-)Span<T>.SingleOrDefault(Predicate<T> predicate)`
64-
- `(Readonly-)Span<T>.SingleOrDefault(T defaultValue)`
65-
- `(Readonly-)Span<T>.SingleOrDefault(Predicate<T> predicate, T defaultValue)`
66-
- `(Readonly-)Span<T>.ElementAt(int index)`
67-
- `(Readonly-)Span<T>.ElementAt(Index index)`
68-
- `(Readonly-)Span<T>.ElementAtOrDefault(int index)`
69-
- `(Readonly-)Span<T>.ElementAtOrDefault(Index index)`
70-
- `(Readonly-)Span<T>.ElementAtOrDefault(int index, T defaultValue)`
71-
- `(Readonly-)Span<T>.ElementAtOrDefault(Index index, T defaultValue)`
72-
- `(Readonly-)Span<T>.Min()`
73-
- `(Readonly-)Span<T>.Min(Func<TSource, TResult> selector)`
74-
- `(Readonly-)Span<T>.MinBy(Func<TSource, TKey> keySelector)`
75-
- `(Readonly-)Span<T>.MinBy(Func<TSource, TKey> keySelector, IComparer<TKey> comparer)`
76-
- `(Readonly-)Span<T>.Max()`
77-
- `(Readonly-)Span<T>.Max(Func<TSource, TResult> selector)`
78-
- `(Readonly-)Span<T>.MaxBy(Func<TSource, TKey> keySelector)`
79-
- `(Readonly-)Span<T>.MaxBy(Func<TSource, TKey> keySelector, IComparer<TKey> comparer)`
11+
**SpanExtensions.Net** aims to help developers use `ReadonlySpan<T>` and `Span<T>` more **productively**, **efficiently** and **safely** and write overall more **performant** Programs.
8012

8113
## Contributing
8214

8315
Thank you for your interest in contributing to this project - Please see [Contributing](CONTRIBUTING.md)!
16+
8417
## License
8518

86-
Copyright (c) draconware-dev. All rights reserved.
19+
Copyright (c) draconware-dev. All rights reserved.
8720

8821
Licensed under the [MIT](../LICENSE) License.

.github/SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
## Reporting a Vulnerability
44

5-
If you find a security vulnerability please message **[email protected]** about the vulnerability and do not, **under no circumstances**, open a public issue.
5+
If you find a security vulnerability please message **[email protected]** about the vulnerability and do not, **under no circumstances**, open a public issue.

Changelog.md

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,30 @@
33
All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6-
and this project adheres not (yet) to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) from v2.0 onwards.
7+
8+
## [2.0.0] - 2025-9-28
9+
10+
### Fixed
11+
12+
- an empty array not being treated as whitespace by range-based Split methods (https://github.com/draconware-dev/SpanExtensions.Net/pull/27)
13+
- the SearchValues-overload of range-based Split methods.
14+
15+
### Changed
16+
17+
- vectorized `Min()` and `Max()`.
18+
- transitioned to semantic versioning.
19+
20+
## [1.5.1] - 2024-12-14
21+
22+
### Fixed
23+
24+
- incorrect ranges returned by the range-based Split method for versions prior to .Net 9.
25+
26+
### Changed
27+
28+
- moved MemoryExtensions containing range-based Split method for versions prior to .Net 9 from `System` to `SpanExtensions`.
29+
- grammatical issues in some documentation comments.
730

831
## [1.5.1] - 2024-12-14
932

@@ -22,49 +45,49 @@ and this project adheres not (yet) to [Semantic Versioning](https://semver.org/s
2245

2346
- implementations of the newly introduced Span.Split methods from .Net 9 for any version prior to .Net 9 to maintain backwards-compatibility across .Net versions.
2447

25-
### Changed
48+
### Changed
2649

2750
- Split extension methods to refer to new split implementations compatible to the ones in .Net 9 and made .Net 9 split methods the default from that version onwards. The original split methods are still accessible as static methods.
2851
- original Split methods are no longer available without passing span as a parameter.
2952

3053
## [1.4.2] - 2024-10-29
3154

32-
### Added
55+
### Added
3356

3457
- `(Readonly-)Span<T>.Count(...)` overloads to all versions before .Net 8 matching these introduced in .Net 8.
3558

36-
### Changed
59+
### Changed
3760

38-
- blocked compilation on .Net 9 due to known incompatibilities, which are to be resolved in version 1.5.
61+
- blocked compilation on .Net 9 due to known incompatibilities, which are to be resolved in version 1.5.
3962

4063
## [1.4.1] - 2024-9-9
4164

42-
### Fixed
65+
### Fixed
4366

4467
- a collision between the `Span<T>.Replace` method provided by SpanExtensions and the one newly provided by .Net 8.
4568

4669
## [1.4] - 2024-9-3
4770

48-
### Added
71+
### Added
4972

5073
- `(Readonly-)Span<T>.Count()`
5174
- `(Readonly-)Span<T>.Count(Predicate<T> predicate)`
5275

53-
### Changed
76+
### Changed
5477

5578
- `Split` to throw an `ArgumentException` instead of an `InvalidCountExceedingBehaviourException`
5679

57-
### Removed
80+
### Removed
5881

5982
- `InvalidCountExceedingBehaviourException`
6083

61-
### Fixed
84+
### Fixed
6285

63-
- various issues with `Split` (https://github.com/draconware-dev/SpanExtensions.Net/pull/11)
86+
- various issues with `Split` (https://github.com/draconware-dev/SpanExtensions.Net/pull/11)
6487

6588
## [1.3] - 2024-3-19
6689

67-
### Added
90+
### Added
6891

6992
- Compatibility with **.Net 8**
7093
- `(Readonly-)Span<T>.First()`
@@ -102,42 +125,42 @@ and this project adheres not (yet) to [Semantic Versioning](https://semver.org/s
102125
- nuget badge to README (https://github.com/draconware-dev/SpanExtensions.Net/pull/12)
103126
- `CountExceedingBehaviour`, which is passed to Split, defining how to properly handle its remaining elements.
104127

105-
### Changed
128+
### Changed
106129

107130
- documentation comments to better reflect the dotnet style (https://github.com/draconware-dev/SpanExtensions.Net/pull/8)
108131
- swapped order of `count` and `stringSplitOptions arguments` in `Split` methods.
109132
- renamed argument `span` in `Split` methods to `source`.
110133

111-
### Fixed
134+
### Fixed
112135

113136
- 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)
114137

115138
## [1.2.1] - 2024-1-25
116139

117-
### Fixed
140+
### Fixed
118141

119142
- Ambiguous Extension Methods (https://github.com/draconware-dev/SpanExtensions.Net/issues/6)
120-
- Correctness of some documentation comments
143+
- Correctness of some documentation comments
121144

122145
## [1.2.0] - 2023-12-28
123146

124-
### Added
147+
### Added
125148

126149
- Missing documentation comments
127150

128-
### Fixed
151+
### Fixed
129152

130153
- Grammatical issues in some documentation comments
131154

132-
### Changed
155+
### Changed
133156

134-
- moved custom Enumerators into `SpanExtensions.Enumerators`
157+
- moved custom Enumerators into `SpanExtensions.Enumerators`
135158
- declared every `GetEnumerator` method in a ref struct as `readonly`
136-
- renamed the source ReadOnlySpan<T> in 10 out of 12 custom Enumerators from *span* to *source*
159+
- renamed the source ReadOnlySpan<T> in 10 out of 12 custom Enumerators from _span_ to _source_
137160

138161
## [1.1.0] - 2023-11-4
139162

140-
### Added
163+
### Added
141164

142165
- Compatibility with **.Net 6**
143166
- Compatibility with **.Net 5**
@@ -149,7 +172,7 @@ and this project adheres not (yet) to [Semantic Versioning](https://semver.org/s
149172
- Missing documentation comments
150173
- Changelog
151174

152-
### Fixed
175+
### Fixed
153176

154177
- Grammatical issues in some documentation comments
155178
- Broken link to the repository on nuget ([#3](https://github.com/draconware-dev/SpanExtensions.Net/pull/3))

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 draconware-dev
3+
Copyright (c) 2025 draconware-dev
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

SpanExtensions.sln

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ Global
1515
Release|Any CPU = Release|Any CPU
1616
EndGlobalSection
1717
GlobalSection(ProjectConfigurationPlatforms) = postSolution
18-
{75DE5AFD-663E-415D-9B95-6BC513BD4A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19-
{75DE5AFD-663E-415D-9B95-6BC513BD4A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{75DE5AFD-663E-415D-9B95-6BC513BD4A07}.Debug|Any CPU.ActiveCfg = Release|Any CPU
19+
{75DE5AFD-663E-415D-9B95-6BC513BD4A07}.Debug|Any CPU.Build.0 = Release|Any CPU
2020
{75DE5AFD-663E-415D-9B95-6BC513BD4A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
2121
{75DE5AFD-663E-415D-9B95-6BC513BD4A07}.Release|Any CPU.Build.0 = Release|Any CPU
2222
{B48A0293-A7FF-4E39-8F8D-57B6F824D70F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2323
{B48A0293-A7FF-4E39-8F8D-57B6F824D70F}.Debug|Any CPU.Build.0 = Debug|Any CPU
2424
{B48A0293-A7FF-4E39-8F8D-57B6F824D70F}.Release|Any CPU.ActiveCfg = Release|Any CPU
2525
{B48A0293-A7FF-4E39-8F8D-57B6F824D70F}.Release|Any CPU.Build.0 = Release|Any CPU
26-
{CE74F420-1038-4E51-AC31-00DA964CC4F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27-
{CE74F420-1038-4E51-AC31-00DA964CC4F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
26+
{CE74F420-1038-4E51-AC31-00DA964CC4F5}.Debug|Any CPU.ActiveCfg = Release|Any CPU
27+
{CE74F420-1038-4E51-AC31-00DA964CC4F5}.Debug|Any CPU.Build.0 = Release|Any CPU
2828
{CE74F420-1038-4E51-AC31-00DA964CC4F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
2929
{CE74F420-1038-4E51-AC31-00DA964CC4F5}.Release|Any CPU.Build.0 = Release|Any CPU
3030
EndGlobalSection

src/Enumerators/System/SpanSplitEnumerator.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
22
using System.Buffers;
3-
using System.Diagnostics;
4-
using System.Runtime.CompilerServices;
53

64
#if !NET9_0_OR_GREATER
75

@@ -62,7 +60,7 @@ internal SpanSplitEnumerator(ReadOnlySpan<T> source, SearchValues<T> searchValue
6260
Delimiter = default!;
6361
SearchValues = searchValues;
6462
DelimiterSpan = default;
65-
mode = SpanSplitEnumeratorMode.Delimiter;
63+
mode = SpanSplitEnumeratorMode.SearchValues;
6664
currentStartIndex = 0;
6765
currentEndIndex = 0;
6866
nextStartIndex = 0;
@@ -118,19 +116,17 @@ public bool MoveNext()
118116
}
119117

120118
currentStartIndex = nextStartIndex;
121-
119+
122120
if(index < 0)
123121
{
124122
currentEndIndex = Span.Length;
125123
nextStartIndex = Span.Length;
126-
127124
mode = (SpanSplitEnumeratorMode)(-1);
128125
return true;
129126
}
130127

131128
currentEndIndex = currentStartIndex + index;
132129
nextStartIndex = currentEndIndex + length;
133-
134130
return true;
135131
}
136132
}

0 commit comments

Comments
 (0)