Skip to content

Commit 5767037

Browse files
committed
Merge branch 'master' into dev/7.0.0
2 parents 5363919 + 4aca259 commit 5767037

File tree

7 files changed

+171
-274
lines changed

7 files changed

+171
-274
lines changed

Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanEnumerable{T}.cs

Lines changed: 34 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -15,94 +15,72 @@ namespace Microsoft.Toolkit.HighPerformance.Enumerables
1515
/// </summary>
1616
/// <typeparam name="T">The type of items to enumerate.</typeparam>
1717
[EditorBrowsable(EditorBrowsableState.Never)]
18-
public readonly ref struct ReadOnlySpanEnumerable<T>
18+
public ref struct ReadOnlySpanEnumerable<T>
1919
{
2020
/// <summary>
21-
/// The source <see cref="ReadOnlySpan{T}"/> instance
21+
/// The source <see cref="ReadOnlySpan{T}"/> instance.
2222
/// </summary>
2323
private readonly ReadOnlySpan<T> span;
2424

25+
/// <summary>
26+
/// The current index within <see cref="span"/>.
27+
/// </summary>
28+
private int index;
29+
2530
/// <summary>
2631
/// Initializes a new instance of the <see cref="ReadOnlySpanEnumerable{T}"/> struct.
2732
/// </summary>
28-
/// <param name="span">The source <see cref="ReadOnlySpan{T}"/> to enumerate.</param>
33+
/// <param name="span">The source <see cref="ReadOnlySpan{T}"/> instance.</param>
2934
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3035
public ReadOnlySpanEnumerable(ReadOnlySpan<T> span)
3136
{
3237
this.span = span;
38+
this.index = -1;
3339
}
3440

3541
/// <summary>
3642
/// Implements the duck-typed <see cref="IEnumerable{T}.GetEnumerator"/> method.
3743
/// </summary>
38-
/// <returns>An <see cref="Enumerator"/> instance targeting the current <see cref="ReadOnlySpan{T}"/> value.</returns>
44+
/// <returns>An <see cref="ReadOnlySpanEnumerable{T}"/> instance targeting the current <see cref="ReadOnlySpan{T}"/> value.</returns>
3945
[MethodImpl(MethodImplOptions.AggressiveInlining)]
40-
public Enumerator GetEnumerator() => new Enumerator(this.span);
46+
public ReadOnlySpanEnumerable<T> GetEnumerator() => this;
4147

4248
/// <summary>
43-
/// An enumerator for a source <see cref="ReadOnlySpan{T}"/> instance.
49+
/// Implements the duck-typed <see cref="System.Collections.IEnumerator.MoveNext"/> method.
4450
/// </summary>
45-
[EditorBrowsable(EditorBrowsableState.Never)]
46-
public ref struct Enumerator
51+
/// <returns><see langword="true"/> whether a new element is available, <see langword="false"/> otherwise</returns>
52+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
53+
public bool MoveNext()
4754
{
48-
/// <summary>
49-
/// The source <see cref="ReadOnlySpan{T}"/> instance.
50-
/// </summary>
51-
private readonly ReadOnlySpan<T> span;
52-
53-
/// <summary>
54-
/// The current index within <see cref="span"/>.
55-
/// </summary>
56-
private int index;
57-
58-
/// <summary>
59-
/// Initializes a new instance of the <see cref="Enumerator"/> struct.
60-
/// </summary>
61-
/// <param name="span">The source <see cref="ReadOnlySpan{T}"/> instance.</param>
62-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
63-
public Enumerator(ReadOnlySpan<T> span)
64-
{
65-
this.span = span;
66-
this.index = -1;
67-
}
55+
int newIndex = this.index + 1;
6856

69-
/// <summary>
70-
/// Implements the duck-typed <see cref="System.Collections.IEnumerator.MoveNext"/> method.
71-
/// </summary>
72-
/// <returns><see langword="true"/> whether a new element is available, <see langword="false"/> otherwise</returns>
73-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
74-
public bool MoveNext()
57+
if (newIndex < this.span.Length)
7558
{
76-
int newIndex = this.index + 1;
59+
this.index = newIndex;
7760

78-
if (newIndex < this.span.Length)
79-
{
80-
this.index = newIndex;
81-
82-
return true;
83-
}
84-
85-
return false;
61+
return true;
8662
}
8763

88-
/// <summary>
89-
/// Gets the duck-typed <see cref="IEnumerator{T}.Current"/> property.
90-
/// </summary>
91-
public Item Current
64+
return false;
65+
}
66+
67+
/// <summary>
68+
/// Gets the duck-typed <see cref="IEnumerator{T}.Current"/> property.
69+
/// </summary>
70+
public Item Current
71+
{
72+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
73+
get
9274
{
93-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
94-
get
95-
{
9675
#if SPAN_RUNTIME_SUPPORT
97-
ref T r0 = ref MemoryMarshal.GetReference(this.span);
98-
ref T ri = ref Unsafe.Add(ref r0, this.index);
76+
ref T r0 = ref MemoryMarshal.GetReference(this.span);
77+
ref T ri = ref Unsafe.Add(ref r0, this.index);
9978

100-
// See comment in SpanEnumerable<T> about this
101-
return new Item(ref ri, this.index);
79+
// See comment in SpanEnumerable<T> about this
80+
return new Item(ref ri, this.index);
10281
#else
103-
return new Item(this.span, this.index);
82+
return new Item(this.span, this.index);
10483
#endif
105-
}
10684
}
10785
}
10886

Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanTokenizer{T}.cs

Lines changed: 47 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -14,119 +14,90 @@ namespace Microsoft.Toolkit.HighPerformance.Enumerables
1414
/// </summary>
1515
/// <typeparam name="T">The type of items to enumerate.</typeparam>
1616
[EditorBrowsable(EditorBrowsableState.Never)]
17-
public readonly ref struct ReadOnlySpanTokenizer<T>
17+
public ref struct ReadOnlySpanTokenizer<T>
1818
where T : IEquatable<T>
1919
{
2020
/// <summary>
21-
/// The source <see cref="ReadOnlySpan{T}"/> instance
21+
/// The source <see cref="ReadOnlySpan{T}"/> instance.
2222
/// </summary>
2323
private readonly ReadOnlySpan<T> span;
2424

2525
/// <summary>
26-
/// The separator <typeparamref name="T"/> item to use.
26+
/// The separator item to use.
2727
/// </summary>
2828
private readonly T separator;
2929

30+
/// <summary>
31+
/// The current initial offset.
32+
/// </summary>
33+
private int start;
34+
35+
/// <summary>
36+
/// The current final offset.
37+
/// </summary>
38+
private int end;
39+
3040
/// <summary>
3141
/// Initializes a new instance of the <see cref="ReadOnlySpanTokenizer{T}"/> struct.
3242
/// </summary>
33-
/// <param name="span">The source <see cref="ReadOnlySpan{T}"/> to tokenize.</param>
34-
/// <param name="separator">The separator <typeparamref name="T"/> item to use.</param>
35-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
43+
/// <param name="span">The source <see cref="ReadOnlySpan{T}"/> instance.</param>
44+
/// <param name="separator">The separator item to use.</param>
3645
public ReadOnlySpanTokenizer(ReadOnlySpan<T> span, T separator)
3746
{
3847
this.span = span;
3948
this.separator = separator;
49+
this.start = 0;
50+
this.end = -1;
4051
}
4152

4253
/// <summary>
4354
/// Implements the duck-typed <see cref="IEnumerable{T}.GetEnumerator"/> method.
4455
/// </summary>
45-
/// <returns>An <see cref="Enumerator"/> instance targeting the current <see cref="ReadOnlySpan{T}"/> value.</returns>
56+
/// <returns>An <see cref="ReadOnlySpanTokenizer{T}"/> instance targeting the current <see cref="ReadOnlySpan{T}"/> value.</returns>
4657
[MethodImpl(MethodImplOptions.AggressiveInlining)]
47-
public Enumerator GetEnumerator() => new Enumerator(this.span, this.separator);
58+
public ReadOnlySpanTokenizer<T> GetEnumerator() => this;
4859

4960
/// <summary>
50-
/// An enumerator for a source <see cref="ReadOnlySpan{T}"/> instance.
61+
/// Implements the duck-typed <see cref="System.Collections.IEnumerator.MoveNext"/> method.
5162
/// </summary>
52-
[EditorBrowsable(EditorBrowsableState.Never)]
53-
public ref struct Enumerator
63+
/// <returns><see langword="true"/> whether a new element is available, <see langword="false"/> otherwise</returns>
64+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
65+
public bool MoveNext()
5466
{
55-
/// <summary>
56-
/// The source <see cref="ReadOnlySpan{T}"/> instance.
57-
/// </summary>
58-
private readonly ReadOnlySpan<T> span;
59-
60-
/// <summary>
61-
/// The separator item to use.
62-
/// </summary>
63-
private readonly T separator;
64-
65-
/// <summary>
66-
/// The current initial offset.
67-
/// </summary>
68-
private int start;
69-
70-
/// <summary>
71-
/// The current final offset.
72-
/// </summary>
73-
private int end;
74-
75-
/// <summary>
76-
/// Initializes a new instance of the <see cref="Enumerator"/> struct.
77-
/// </summary>
78-
/// <param name="span">The source <see cref="ReadOnlySpan{T}"/> instance.</param>
79-
/// <param name="separator">The separator item to use.</param>
80-
public Enumerator(ReadOnlySpan<T> span, T separator)
81-
{
82-
this.span = span;
83-
this.separator = separator;
84-
this.start = 0;
85-
this.end = -1;
86-
}
67+
int
68+
newEnd = this.end + 1,
69+
length = this.span.Length;
8770

88-
/// <summary>
89-
/// Implements the duck-typed <see cref="System.Collections.IEnumerator.MoveNext"/> method.
90-
/// </summary>
91-
/// <returns><see langword="true"/> whether a new element is available, <see langword="false"/> otherwise</returns>
92-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
93-
public bool MoveNext()
71+
// Additional check if the separator is not the last character
72+
if (newEnd <= length)
9473
{
95-
int
96-
newEnd = this.end + 1,
97-
length = this.span.Length;
98-
99-
// Additional check if the separator is not the last character
100-
if (newEnd <= length)
101-
{
102-
this.start = newEnd;
74+
this.start = newEnd;
10375

104-
int index = this.span.Slice(newEnd).IndexOf(this.separator);
76+
int index = this.span.Slice(newEnd).IndexOf(this.separator);
10577

106-
// Extract the current subsequence
107-
if (index >= 0)
108-
{
109-
this.end = newEnd + index;
110-
111-
return true;
112-
}
113-
114-
this.end = length;
78+
// Extract the current subsequence
79+
if (index >= 0)
80+
{
81+
this.end = newEnd + index;
11582

11683
return true;
11784
}
11885

119-
return false;
120-
}
86+
this.end = length;
12187

122-
/// <summary>
123-
/// Gets the duck-typed <see cref="IEnumerator{T}.Current"/> property.
124-
/// </summary>
125-
public ReadOnlySpan<T> Current
126-
{
127-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
128-
get => this.span.Slice(this.start, this.end - this.start);
88+
return true;
12989
}
90+
91+
return false;
92+
}
93+
94+
/// <summary>
95+
/// Gets the duck-typed <see cref="IEnumerator{T}.Current"/> property.
96+
/// </summary>
97+
public ReadOnlySpan<T> Current
98+
{
99+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
100+
get => this.span.Slice(this.start, this.end - this.start);
130101
}
131102
}
132103
}

0 commit comments

Comments
 (0)