Skip to content

Commit 05c4a08

Browse files
committed
some
1 parent 51ec89f commit 05c4a08

File tree

8 files changed

+633
-9
lines changed

8 files changed

+633
-9
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
3+
namespace SpanExtensions
4+
{
5+
public static partial class ReadOnlySpanExtensions
6+
{
7+
/// <summary>
8+
/// Returns the first element in a <see cref="ReadOnlySpan{T}"/>.
9+
/// </summary>
10+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
11+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the first element of.</param>
12+
/// <returns>The first element in <paramref name="source"/>.</returns>
13+
/// <exception cref="InvalidOperationException"><paramref name="source"/> is empty.</exception>
14+
public static T First<T>(this ReadOnlySpan<T> source)
15+
{
16+
if(source.IsEmpty)
17+
{
18+
throw new InvalidOperationException($"{nameof(source)} cannot be empty.");
19+
}
20+
return source[0];
21+
}
22+
23+
/// <summary>
24+
/// Returns the first element in a <see cref="ReadOnlySpan{T}"/> that satisfies a specified condition.
25+
/// </summary>
26+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
27+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the first element of.</param>
28+
/// <param name="predicate">A function to test each element for a condition.</param>
29+
/// <returns>The first element in <paramref name="source"/> that passes the test in the specified <paramref name="predicate"/> function.</returns>
30+
/// <exception cref="ArgumentNullException"><paramref name="predicate"/> is null.</exception>
31+
/// <exception cref="InvalidOperationException">No element satisfies the condition in <paramref name="predicate"/>. -or- <paramref name="source"/> is empty.</exception>
32+
public static T First<T>(this ReadOnlySpan<T> source, Predicate<T> predicate)
33+
{
34+
if(predicate is null)
35+
{
36+
throw new ArgumentNullException(nameof(predicate));
37+
}
38+
if(source.IsEmpty)
39+
{
40+
throw new InvalidOperationException($"{nameof(source)} cannot be empty.");
41+
}
42+
for(int i = 0; i < source.Length; i++)
43+
{
44+
T item = source[i];
45+
46+
if(predicate(item))
47+
{
48+
return item;
49+
}
50+
}
51+
throw new InvalidOperationException("No element matched the specified condition.");
52+
}
53+
}
54+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
using System;
2+
3+
namespace SpanExtensions
4+
{
5+
public static partial class ReadOnlySpanExtensions
6+
{
7+
/// <summary>
8+
/// Returns the first element in a <see cref="ReadOnlySpan{T}"/>, or a specified default value if the <see cref="ReadOnlySpan{T}"/> contains no elements..
9+
/// </summary>
10+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
11+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the first element of.</param>
12+
/// <param name="defaultValue">The default value to return if <paramref name="source"/> is empty.</param>
13+
/// <returns><paramref name="defaultValue"/> if <paramref name="source"/> is empty; otherwise, the first element in <paramref name="source"/>.</returns>
14+
public static T FirstOrDefault<T>(this ReadOnlySpan<T> source, T defaultValue)
15+
{
16+
if(source.IsEmpty)
17+
{
18+
return defaultValue;
19+
}
20+
return source[0];
21+
}
22+
23+
/// <summary>
24+
/// Returns the first element in a <see cref="ReadOnlySpan{T}"/> that satisfies a specified condition or a specified default value if no such element is found.
25+
/// </summary>
26+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
27+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the first element of.</param>
28+
/// <param name="predicate">A function to test each element for a condition.</param>
29+
/// <param name="defaultValue">The default value to return if <paramref name="source"/> is empty.</param>
30+
/// <returns>default(T) if <paramref name="source"/> is empty or if no element passes the test specified by <paramref name="predicate"/>; otherwise, the first element in <paramref name="source"/> that passes the test specified by <paramref name="predicate"/>.</returns>
31+
/// <exception cref="ArgumentNullException"><paramref name="predicate"/> is null.</exception>
32+
public static T FirstOrDefault<T>(this ReadOnlySpan<T> source, Predicate<T> predicate, T defaultValue)
33+
{
34+
if(predicate is null)
35+
{
36+
throw new ArgumentNullException(nameof(predicate));
37+
}
38+
if(source.IsEmpty)
39+
{
40+
return defaultValue;
41+
}
42+
for(int i = 0; i < source.Length; i++)
43+
{
44+
T item = source[i];
45+
46+
if(predicate(item))
47+
{
48+
return item;
49+
}
50+
}
51+
return defaultValue;
52+
}
53+
#if NETCOREAPP1_0_OR_GREATER
54+
/// <summary>
55+
/// Returns the first element in a <see cref="ReadOnlySpan{T}"/>, or a specified default value if the <see cref="ReadOnlySpan{T}"/> contains no elements..
56+
/// </summary>
57+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
58+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the first element of.</param>
59+
/// <returns>default(T) if <paramref name="source"/> is empty; otherwise, the first element in <paramref name="source"/>.</returns>
60+
public static T? FirstOrDefault<T>(this ReadOnlySpan<T> source)
61+
{
62+
if(source.IsEmpty)
63+
{
64+
return default(T);
65+
}
66+
return source[0];
67+
}
68+
69+
/// <summary>
70+
/// Returns the first element in a <see cref="ReadOnlySpan{T}"/> that satisfies a specified conditionor a default value if no such element is found.
71+
/// </summary>
72+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
73+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the first element of.</param>
74+
/// <param name="predicate">A function to test each element for a condition.</param>
75+
/// <returns>default(T) if <paramref name="source"/> is empty or if no element passes the test specified by <paramref name="predicate"/>; otherwise, the first element in <paramref name="source"/>.</returns>
76+
/// <exception cref="ArgumentNullException"><paramref name="predicate"/> is null.</exception>
77+
public static T? FirstOrDefault<T>(this ReadOnlySpan<T> source, Predicate<T> predicate)
78+
{
79+
if(predicate is null)
80+
{
81+
throw new ArgumentNullException(nameof(predicate));
82+
}
83+
if(source.IsEmpty)
84+
{
85+
return default(T);
86+
}
87+
for(int i = 0; i < source.Length; i++)
88+
{
89+
T item = source[i];
90+
91+
if(predicate(item))
92+
{
93+
return item;
94+
}
95+
}
96+
return default(T);
97+
}
98+
#elif NETSTANDARD2_1
99+
#pragma warning disable CS8603 // Possible null reference return.
100+
/// <summary>
101+
/// Returns the first element in a <see cref="ReadOnlySpan{T}"/>, or a specified default value if the <see cref="ReadOnlySpan{T}"/> contains no elements..
102+
/// </summary>
103+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
104+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the first element of.</param>
105+
/// <returns>default(T) if <paramref name="source"/> is empty; otherwise, the first element in <paramref name="source"/>.</returns>
106+
public static T FirstOrDefault<T>(this ReadOnlySpan<T> source)
107+
{
108+
if(source.IsEmpty)
109+
{
110+
return default(T);
111+
}
112+
return source[0];
113+
}
114+
115+
/// <summary>
116+
/// Returns the first element in a <see cref="ReadOnlySpan{T}"/> that satisfies a specified conditionor a default value if no such element is found.
117+
/// </summary>
118+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
119+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the first element of.</param>
120+
/// <param name="predicate">A function to test each element for a condition.</param>
121+
/// <returns>default(T) if <paramref name="source"/> is empty or if no element passes the test specified by <paramref name="predicate"/>; otherwise, the first element in <paramref name="source"/>.</returns>
122+
/// <exception cref="ArgumentNullException"><paramref name="predicate"/> is null.</exception>
123+
public static T FirstOrDefault<T>(this ReadOnlySpan<T> source, Predicate<T> predicate)
124+
{
125+
if(predicate is null)
126+
{
127+
throw new ArgumentNullException(nameof(predicate));
128+
}
129+
if(source.IsEmpty)
130+
{
131+
return default(T);
132+
133+
}
134+
for(int i = 0; i < source.Length; i++)
135+
{
136+
T item = source[i];
137+
138+
if(predicate(item))
139+
{
140+
return item;
141+
}
142+
}
143+
return default(T);
144+
}
145+
#pragma warning restore CS8603 // Possible null reference return.
146+
#endif
147+
}
148+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
3+
namespace SpanExtensions
4+
{
5+
public static partial class ReadOnlySpanExtensions
6+
{
7+
/// <summary>
8+
/// Returns the last element in a <see cref="ReadOnlySpan{T}"/>.
9+
/// </summary>
10+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
11+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the last element of.</param>
12+
/// <returns>The last element in <paramref name="source"/>.</returns>
13+
/// <exception cref="InvalidOperationException"><paramref name="source"/> is empty.</exception>
14+
public static T Last<T>(this ReadOnlySpan<T> source)
15+
{
16+
if(source.IsEmpty)
17+
{
18+
throw new InvalidOperationException($"{nameof(source)} cannot be empty.");
19+
}
20+
return source[^1];
21+
}
22+
23+
/// <summary>
24+
/// Returns the last element in a <see cref="ReadOnlySpan{T}"/> that satisfies a specified condition.
25+
/// </summary>
26+
/// <typeparam name="T">The type of elements in <paramref name="source"/>.</typeparam>
27+
/// <param name="source">The <see cref="ReadOnlySpan{T}"/> to return the last element of.</param>
28+
/// <param name="predicate">A function to test each element for a condition.</param>
29+
/// <returns>The last element in <paramref name="source"/> that passes the test in the specified <paramref name="predicate"/> function.</returns>
30+
/// <exception cref="ArgumentNullException"><paramref name="predicate"/> is null.</exception>
31+
/// <exception cref="InvalidOperationException">No element satisfies the condition in <paramref name="predicate"/>. -or- <paramref name="source"/> is empty.</exception>
32+
public static T Last<T>(this ReadOnlySpan<T> source, Predicate<T> predicate)
33+
{
34+
if(predicate is null)
35+
{
36+
throw new ArgumentNullException(nameof(predicate));
37+
}
38+
if(source.IsEmpty)
39+
{
40+
throw new InvalidOperationException($"{nameof(source)} cannot be empty.");
41+
}
42+
for(int i = source.Length - 1; i > 0; i--)
43+
{
44+
T item = source[i];
45+
46+
if(predicate(item))
47+
{
48+
return item;
49+
}
50+
}
51+
throw new InvalidOperationException("No element matched the specified condition.");
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)