-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
EDITED 11/5/2024 by @stephentoub with updated proposal:
namespace System;
public static class MemoryExtensions
{
+ public static bool Contains<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static bool ContainsAny<T>(this ReadOnlySpan<T> span, T value0, T value1, IEqualityComparer<T>? comparer = null);
+ public static bool ContainsAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2, IEqualityComparer<T>? comparer = null);
+ public static bool ContainsAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values, IEqualityComparer<T>? comparer = null);
+ public static bool ContainsAnyExcept<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static bool ContainsAnyExcept<T>(this ReadOnlySpan<T> span, T value0, T value1, IEqualityComparer<T>? comparer = null);
+ public static bool ContainsAnyExcept<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2, IEqualityComparer<T>? comparer = null);
+ public static bool ContainsAnyExcept<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values, IEqualityComparer<T>? comparer = null);
+ public static int Count<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static int Count<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value, IEqualityComparer<T>? comparer = null);
+ public static bool EndsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value, IEqualityComparer<T>? comparer = null);
+ public static bool EndsWith<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value, IEqualityComparer<T>? comparer = null);
+ public static bool StartsWith<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static int IndexOf<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, IEqualityComparer<T>? comparer = null);
+ public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2, IEqualityComparer<T>? comparer = null);
+ public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values, IEqualityComparer<T>? comparer = null);
+ public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value, IEqualityComparer<T>? comparer = null);
+ public static int IndexOfAnyExcept<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static int IndexOfAnyExcept<T>(this ReadOnlySpan<T> span, T value0, T value1, IEqualityComparer<T>? comparer = null);
+ public static int IndexOfAnyExcept<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2, IEqualityComparer<T>? comparer = null);
+ public static int IndexOfAnyExcept<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOfAnyExcept<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOfAnyExcept<T>(this ReadOnlySpan<T> span, T value0, T value1, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOfAnyExcept<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2, IEqualityComparer<T>? comparer = null);
+ public static int LastIndexOfAnyExcept<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values, IEqualityComparer<T>? comparer = null);
+ public static void Replace<T>(this ReadOnlySpan<T> source, Span<T> destination, T oldValue, T newValue, IEqualityComparer<T>? comparer = null);
+ public static int SequenceCompareTo<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, IComparer<T>? comparer = null);
}
Notes:
- The above systematically adds
IEqualityComparer<T>? comparer = null
overloads for existing overloads without the comparer but constrainingwhere T : IEquatable<T>?
. Exceptions to this: -
- Overloads for
Trim
/TrimStart
/TrimEnd
andSplit
/SplitAny
as there are a lot of them, and I've not yet seen a need. The return type also complicates things, e.g.Split
returns aSpanSplitEnumerable<T>
that constrains the T.
- Overloads for
-
- Overloads for
this Span
. Per [API Proposal]: Apply [OverloadResolutionPriority] to Span-based overloads #109549, they're no longer needed.
- Overloads for
- The
IEquatable<T>
overloads will continue to bind when no comparer is provided and the T is IEquatable. The new overloads will be used when either a comparer is provided or when T isn't IEquatable, so the signatures just naturally become usable in more places.
Old proposal:
https://github.com/dotnet/corefx/issues/27526 was reviewed and API-approved to add four overloads:
public static class MemoryExtensions
{
bool Contains<T>(this Span<T> span, T value);
bool Contains<T>(this ReadOnlySpan<T> span, T value);
bool Contains<T>(this Span<T> span, T value, IEqualityComparer<T> comparer);
bool Contains<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T> comparer);
}
However, only the first two got implemented. The latter two were flagged as being inconsistent:
https://github.com/dotnet/corefx/issues/27526#issuecomment-422467532
The other 2 APIs are inconsistent with the rest of System.Memory public surface (none of the several hundreds other System.Memory APIs take IEqualityComparer). I assume that this was oversight during API review. We should have a new issue opened to discuss the IEqualityComparer overloads. We should either add the overloads that take IEqualityComparer everywhere in System.Memory (ie add ~30 new APIs), or nowhere. It does not make sense to add them to a random subset.
Opening this issue to track those.