diff --git a/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanEnumerable{T}.cs b/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanEnumerable{T}.cs
index 51b8f675677..29d42924536 100644
--- a/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanEnumerable{T}.cs
+++ b/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanEnumerable{T}.cs
@@ -15,94 +15,72 @@ namespace Microsoft.Toolkit.HighPerformance.Enumerables
///
/// The type of items to enumerate.
[EditorBrowsable(EditorBrowsableState.Never)]
- public readonly ref struct ReadOnlySpanEnumerable
+ public ref struct ReadOnlySpanEnumerable
{
///
- /// The source instance
+ /// The source instance.
///
private readonly ReadOnlySpan span;
+ ///
+ /// The current index within .
+ ///
+ private int index;
+
///
/// Initializes a new instance of the struct.
///
- /// The source to enumerate.
+ /// The source instance.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpanEnumerable(ReadOnlySpan span)
{
this.span = span;
+ this.index = -1;
}
///
/// Implements the duck-typed method.
///
- /// An instance targeting the current value.
+ /// An instance targeting the current value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Enumerator GetEnumerator() => new Enumerator(this.span);
+ public ReadOnlySpanEnumerable GetEnumerator() => this;
///
- /// An enumerator for a source instance.
+ /// Implements the duck-typed method.
///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ref struct Enumerator
+ /// whether a new element is available, otherwise
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool MoveNext()
{
- ///
- /// The source instance.
- ///
- private readonly ReadOnlySpan span;
-
- ///
- /// The current index within .
- ///
- private int index;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The source instance.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Enumerator(ReadOnlySpan span)
- {
- this.span = span;
- this.index = -1;
- }
+ int newIndex = this.index + 1;
- ///
- /// Implements the duck-typed method.
- ///
- /// whether a new element is available, otherwise
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool MoveNext()
+ if (newIndex < this.span.Length)
{
- int newIndex = this.index + 1;
+ this.index = newIndex;
- if (newIndex < this.span.Length)
- {
- this.index = newIndex;
-
- return true;
- }
-
- return false;
+ return true;
}
- ///
- /// Gets the duck-typed property.
- ///
- public Item Current
+ return false;
+ }
+
+ ///
+ /// Gets the duck-typed property.
+ ///
+ public Item Current
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
{
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
#if SPAN_RUNTIME_SUPPORT
- ref T r0 = ref MemoryMarshal.GetReference(this.span);
- ref T ri = ref Unsafe.Add(ref r0, this.index);
+ ref T r0 = ref MemoryMarshal.GetReference(this.span);
+ ref T ri = ref Unsafe.Add(ref r0, this.index);
- // See comment in SpanEnumerable about this
- return new Item(ref ri, this.index);
+ // See comment in SpanEnumerable about this
+ return new Item(ref ri, this.index);
#else
- return new Item(this.span, this.index);
+ return new Item(this.span, this.index);
#endif
- }
}
}
diff --git a/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanTokenizer{T}.cs b/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanTokenizer{T}.cs
index 5a9c7d13823..3977f5829f8 100644
--- a/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanTokenizer{T}.cs
+++ b/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlySpanTokenizer{T}.cs
@@ -14,119 +14,90 @@ namespace Microsoft.Toolkit.HighPerformance.Enumerables
///
/// The type of items to enumerate.
[EditorBrowsable(EditorBrowsableState.Never)]
- public readonly ref struct ReadOnlySpanTokenizer
+ public ref struct ReadOnlySpanTokenizer
where T : IEquatable
{
///
- /// The source instance
+ /// The source instance.
///
private readonly ReadOnlySpan span;
///
- /// The separator item to use.
+ /// The separator item to use.
///
private readonly T separator;
+ ///
+ /// The current initial offset.
+ ///
+ private int start;
+
+ ///
+ /// The current final offset.
+ ///
+ private int end;
+
///
/// Initializes a new instance of the struct.
///
- /// The source to tokenize.
- /// The separator item to use.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ /// The source instance.
+ /// The separator item to use.
public ReadOnlySpanTokenizer(ReadOnlySpan span, T separator)
{
this.span = span;
this.separator = separator;
+ this.start = 0;
+ this.end = -1;
}
///
/// Implements the duck-typed method.
///
- /// An instance targeting the current value.
+ /// An instance targeting the current value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Enumerator GetEnumerator() => new Enumerator(this.span, this.separator);
+ public ReadOnlySpanTokenizer GetEnumerator() => this;
///
- /// An enumerator for a source instance.
+ /// Implements the duck-typed method.
///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ref struct Enumerator
+ /// whether a new element is available, otherwise
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool MoveNext()
{
- ///
- /// The source instance.
- ///
- private readonly ReadOnlySpan span;
-
- ///
- /// The separator item to use.
- ///
- private readonly T separator;
-
- ///
- /// The current initial offset.
- ///
- private int start;
-
- ///
- /// The current final offset.
- ///
- private int end;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The source instance.
- /// The separator item to use.
- public Enumerator(ReadOnlySpan span, T separator)
- {
- this.span = span;
- this.separator = separator;
- this.start = 0;
- this.end = -1;
- }
+ int
+ newEnd = this.end + 1,
+ length = this.span.Length;
- ///
- /// Implements the duck-typed method.
- ///
- /// whether a new element is available, otherwise
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool MoveNext()
+ // Additional check if the separator is not the last character
+ if (newEnd <= length)
{
- int
- newEnd = this.end + 1,
- length = this.span.Length;
-
- // Additional check if the separator is not the last character
- if (newEnd <= length)
- {
- this.start = newEnd;
+ this.start = newEnd;
- int index = this.span.Slice(newEnd).IndexOf(this.separator);
+ int index = this.span.Slice(newEnd).IndexOf(this.separator);
- // Extract the current subsequence
- if (index >= 0)
- {
- this.end = newEnd + index;
-
- return true;
- }
-
- this.end = length;
+ // Extract the current subsequence
+ if (index >= 0)
+ {
+ this.end = newEnd + index;
return true;
}
- return false;
- }
+ this.end = length;
- ///
- /// Gets the duck-typed property.
- ///
- public ReadOnlySpan Current
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => this.span.Slice(this.start, this.end - this.start);
+ return true;
}
+
+ return false;
+ }
+
+ ///
+ /// Gets the duck-typed property.
+ ///
+ public ReadOnlySpan Current
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => this.span.Slice(this.start, this.end - this.start);
}
}
}
diff --git a/Microsoft.Toolkit.HighPerformance/Enumerables/SpanEnumerable{T}.cs b/Microsoft.Toolkit.HighPerformance/Enumerables/SpanEnumerable{T}.cs
index 1db240cc447..791f509339d 100644
--- a/Microsoft.Toolkit.HighPerformance/Enumerables/SpanEnumerable{T}.cs
+++ b/Microsoft.Toolkit.HighPerformance/Enumerables/SpanEnumerable{T}.cs
@@ -15,99 +15,77 @@ namespace Microsoft.Toolkit.HighPerformance.Enumerables
///
/// The type of items to enumerate.
[EditorBrowsable(EditorBrowsableState.Never)]
- public readonly ref struct SpanEnumerable
+ public ref struct SpanEnumerable
{
///
- /// The source instance
+ /// The source instance.
///
private readonly Span span;
+ ///
+ /// The current index within .
+ ///
+ private int index;
+
///
/// Initializes a new instance of the struct.
///
- /// The source to enumerate.
+ /// The source instance.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SpanEnumerable(Span span)
{
this.span = span;
+ this.index = -1;
}
///
/// Implements the duck-typed method.
///
- /// An instance targeting the current value.
+ /// An instance targeting the current value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Enumerator GetEnumerator() => new Enumerator(this.span);
+ public SpanEnumerable GetEnumerator() => this;
///
- /// An enumerator for a source instance.
+ /// Implements the duck-typed method.
///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ref struct Enumerator
+ /// whether a new element is available, otherwise
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool MoveNext()
{
- ///
- /// The source instance.
- ///
- private readonly Span span;
-
- ///
- /// The current index within .
- ///
- private int index;
+ int newIndex = this.index + 1;
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The source instance.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Enumerator(Span span)
+ if (newIndex < this.span.Length)
{
- this.span = span;
- this.index = -1;
- }
+ this.index = newIndex;
- ///
- /// Implements the duck-typed method.
- ///
- /// whether a new element is available, otherwise
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool MoveNext()
- {
- int newIndex = this.index + 1;
-
- if (newIndex < this.span.Length)
- {
- this.index = newIndex;
-
- return true;
- }
-
- return false;
+ return true;
}
- ///
- /// Gets the duck-typed property.
- ///
- public Item Current
+ return false;
+ }
+
+ ///
+ /// Gets the duck-typed property.
+ ///
+ public Item Current
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
{
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
#if SPAN_RUNTIME_SUPPORT
- ref T r0 = ref MemoryMarshal.GetReference(this.span);
- ref T ri = ref Unsafe.Add(ref r0, this.index);
-
- // On .NET Standard 2.1 we can save 4 bytes by piggybacking
- // the current index in the length of the wrapped span.
- // We're going to use the first item as the target reference,
- // and the length as a host for the current original offset.
- // This is not possible on .NET Standard 2.1 as we lack
- // the API to create spans from arbitrary references.
- return new Item(ref ri, this.index);
+ ref T r0 = ref MemoryMarshal.GetReference(this.span);
+ ref T ri = ref Unsafe.Add(ref r0, this.index);
+
+ // On .NET Standard 2.1 we can save 4 bytes by piggybacking
+ // the current index in the length of the wrapped span.
+ // We're going to use the first item as the target reference,
+ // and the length as a host for the current original offset.
+ // This is not possible on .NET Standard 2.1 as we lack
+ // the API to create spans from arbitrary references.
+ return new Item(ref ri, this.index);
#else
- return new Item(this.span, this.index);
+ return new Item(this.span, this.index);
#endif
- }
}
}
diff --git a/Microsoft.Toolkit.HighPerformance/Enumerables/SpanTokenizer{T}.cs b/Microsoft.Toolkit.HighPerformance/Enumerables/SpanTokenizer{T}.cs
index a3034d67a0a..953eb535f0b 100644
--- a/Microsoft.Toolkit.HighPerformance/Enumerables/SpanTokenizer{T}.cs
+++ b/Microsoft.Toolkit.HighPerformance/Enumerables/SpanTokenizer{T}.cs
@@ -14,119 +14,90 @@ namespace Microsoft.Toolkit.HighPerformance.Enumerables
///
/// The type of items to enumerate.
[EditorBrowsable(EditorBrowsableState.Never)]
- public readonly ref struct SpanTokenizer
+ public ref struct SpanTokenizer
where T : IEquatable
{
///
- /// The source instance
+ /// The source instance.
///
private readonly Span span;
///
- /// The separator item to use.
+ /// The separator item to use.
///
private readonly T separator;
+ ///
+ /// The current initial offset.
+ ///
+ private int start;
+
+ ///
+ /// The current final offset.
+ ///
+ private int end;
+
///
/// Initializes a new instance of the struct.
///
- /// The source to tokenize.
- /// The separator item to use.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ /// The source instance.
+ /// The separator item to use.
public SpanTokenizer(Span span, T separator)
{
this.span = span;
this.separator = separator;
+ this.start = 0;
+ this.end = -1;
}
///
/// Implements the duck-typed method.
///
- /// An instance targeting the current value.
+ /// An instance targeting the current value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Enumerator GetEnumerator() => new Enumerator(this.span, this.separator);
+ public SpanTokenizer GetEnumerator() => this;
///
- /// An enumerator for a source instance.
+ /// Implements the duck-typed method.
///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ref struct Enumerator
+ /// whether a new element is available, otherwise
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool MoveNext()
{
- ///
- /// The source instance.
- ///
- private readonly Span span;
-
- ///
- /// The separator item to use.
- ///
- private readonly T separator;
-
- ///
- /// The current initial offset.
- ///
- private int start;
-
- ///
- /// The current final offset.
- ///
- private int end;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The source instance.
- /// The separator item to use.
- public Enumerator(Span span, T separator)
- {
- this.span = span;
- this.separator = separator;
- this.start = 0;
- this.end = -1;
- }
+ int
+ newEnd = this.end + 1,
+ length = this.span.Length;
- ///
- /// Implements the duck-typed method.
- ///
- /// whether a new element is available, otherwise
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool MoveNext()
+ // Additional check if the separator is not the last character
+ if (newEnd <= length)
{
- int
- newEnd = this.end + 1,
- length = this.span.Length;
-
- // Additional check if the separator is not the last character
- if (newEnd <= length)
- {
- this.start = newEnd;
+ this.start = newEnd;
- int index = this.span.Slice(newEnd).IndexOf(this.separator);
+ int index = this.span.Slice(newEnd).IndexOf(this.separator);
- // Extract the current subsequence
- if (index >= 0)
- {
- this.end = newEnd + index;
-
- return true;
- }
-
- this.end = length;
+ // Extract the current subsequence
+ if (index >= 0)
+ {
+ this.end = newEnd + index;
return true;
}
- return false;
- }
+ this.end = length;
- ///
- /// Gets the duck-typed property.
- ///
- public Span Current
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => this.span.Slice(this.start, this.end - this.start);
+ return true;
}
+
+ return false;
+ }
+
+ ///
+ /// Gets the duck-typed property.
+ ///
+ public Span Current
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => this.span.Slice(this.start, this.end - this.start);
}
}
}