diff --git a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs index fd6229f70c1b0..25a7e17a6dc07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs @@ -461,12 +461,25 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOf(this Span span, ReadOnlySpan value) where T : IEquatable? { - if (Unsafe.SizeOf() == sizeof(byte) && RuntimeHelpers.IsBitwiseEquatable()) - return SpanHelpers.LastIndexOf( - ref Unsafe.As(ref MemoryMarshal.GetReference(span)), - span.Length, - ref Unsafe.As(ref MemoryMarshal.GetReference(value)), - value.Length); + if (RuntimeHelpers.IsBitwiseEquatable()) + { + if (Unsafe.SizeOf() == sizeof(byte)) + { + return SpanHelpers.LastIndexOf( + ref Unsafe.As(ref MemoryMarshal.GetReference(span)), + span.Length, + ref Unsafe.As(ref MemoryMarshal.GetReference(value)), + value.Length); + } + else if (Unsafe.SizeOf() == sizeof(char)) + { + return SpanHelpers.LastIndexOf( + ref Unsafe.As(ref MemoryMarshal.GetReference(span)), + span.Length, + ref Unsafe.As(ref MemoryMarshal.GetReference(value)), + value.Length); + } + } return SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length); } @@ -1301,23 +1314,50 @@ public static int IndexOfAny(this ReadOnlySpan span, ReadOnlySpan value { if (Unsafe.SizeOf() == sizeof(byte)) { + ref byte spanRef = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); ref byte valueRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); - if (values.Length == 2) - { - return SpanHelpers.IndexOfAnyValueType( - ref Unsafe.As(ref MemoryMarshal.GetReference(span)), - valueRef, - Unsafe.Add(ref valueRef, 1), - span.Length); - } - else if (values.Length == 3) + switch (values.Length) { - return SpanHelpers.IndexOfAnyValueType( - ref Unsafe.As(ref MemoryMarshal.GetReference(span)), - valueRef, - Unsafe.Add(ref valueRef, 1), - Unsafe.Add(ref valueRef, 2), - span.Length); + case 0: + return -1; + + case 1: + return SpanHelpers.IndexOfValueType(ref spanRef, valueRef, span.Length); + + case 2: + return SpanHelpers.IndexOfAnyValueType( + ref spanRef, + valueRef, + Unsafe.Add(ref valueRef, 1), + span.Length); + + case 3: + return SpanHelpers.IndexOfAnyValueType( + ref spanRef, + valueRef, + Unsafe.Add(ref valueRef, 1), + Unsafe.Add(ref valueRef, 2), + span.Length); + +#if !MONO // We don't have a mono overload for 4 values + case 4: + return SpanHelpers.IndexOfAnyValueType( + ref spanRef, + valueRef, + Unsafe.Add(ref valueRef, 1), + Unsafe.Add(ref valueRef, 2), + Unsafe.Add(ref valueRef, 3), + span.Length); +#endif + case 5: + return SpanHelpers.IndexOfAnyValueType( + ref spanRef, + valueRef, + Unsafe.Add(ref valueRef, 1), + Unsafe.Add(ref valueRef, 2), + Unsafe.Add(ref valueRef, 3), + Unsafe.Add(ref valueRef, 4), + span.Length); } } @@ -1478,18 +1518,8 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// /// The span to search. /// The set of values to search for. - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny(this Span span, ReadOnlySpan values) where T : IEquatable? - { - if (Unsafe.SizeOf() == sizeof(byte) && RuntimeHelpers.IsBitwiseEquatable()) - return SpanHelpers.LastIndexOfAny( - ref Unsafe.As(ref MemoryMarshal.GetReference(span)), - span.Length, - ref Unsafe.As(ref MemoryMarshal.GetReference(values)), - values.Length); - - return SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length); - } + => LastIndexOfAny((ReadOnlySpan)span, values); /// /// Searches for the last index of any of the specified values similar to calling LastIndexOf several times with the logical OR operator. If not found, returns -1. @@ -1570,23 +1600,41 @@ public static int LastIndexOfAny(this ReadOnlySpan span, ReadOnlySpan v { if (Unsafe.SizeOf() == sizeof(byte)) { + ref byte spanRef = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); ref byte valueRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); - if (values.Length == 2) - { - return SpanHelpers.LastIndexOfAnyValueType( - ref Unsafe.As(ref MemoryMarshal.GetReference(span)), - valueRef, - Unsafe.Add(ref valueRef, 1), - span.Length); - } - else if (values.Length == 3) + switch (values.Length) { - return SpanHelpers.LastIndexOfAnyValueType( - ref Unsafe.As(ref MemoryMarshal.GetReference(span)), - valueRef, - Unsafe.Add(ref valueRef, 1), - Unsafe.Add(ref valueRef, 2), - span.Length); + case 0: + return -1; + + case 1: + return SpanHelpers.LastIndexOfValueType(ref spanRef, valueRef, span.Length); + + case 2: + return SpanHelpers.LastIndexOfAnyValueType( + ref spanRef, + valueRef, + Unsafe.Add(ref valueRef, 1), + span.Length); + + case 3: + return SpanHelpers.LastIndexOfAnyValueType( + ref spanRef, + valueRef, + Unsafe.Add(ref valueRef, 1), + Unsafe.Add(ref valueRef, 2), + span.Length); + +#if !MONO // We don't have a mono overload for 4 values + case 4: + return SpanHelpers.LastIndexOfAnyValueType( + ref spanRef, + valueRef, + Unsafe.Add(ref valueRef, 1), + Unsafe.Add(ref valueRef, 2), + Unsafe.Add(ref valueRef, 3), + span.Length); +#endif } }