Fix Issue 11111 - std.algorithm.canFind should support Needles...

The requirement that each needle must be a range is arbitrary, so remove
it.
Note: This overload of `canFind` calls `find(haystack, needles)` which
calls `startsWith`, which accepts mixed element and range needles.
This commit is contained in:
Nick Treleaven 2023-11-06 13:00:15 +00:00
parent 585ddbe691
commit a2c2f79dfa

View file

@ -2376,9 +2376,9 @@ is considered to be 1.) The strategy used in searching several
subranges at once maximizes cache usage by moving in `haystack` as
few times as possible.
*/
Tuple!(Range, size_t) find(alias pred = "a == b", Range, Ranges...)
(Range haystack, Ranges needles)
if (Ranges.length > 1 && is(typeof(startsWith!pred(haystack, needles))))
Tuple!(Range, size_t) find(alias pred = "a == b", Range, Needles...)
(Range haystack, Needles needles)
if (Needles.length > 1 && is(typeof(startsWith!pred(haystack, needles))))
{
for (;; haystack.popFront())
{
@ -2572,9 +2572,8 @@ template canFind(alias pred="a == b")
without having to deal with the tuple that $(LREF find) returns for the
same operation.
+/
size_t canFind(Range, Ranges...)(Range haystack, scope Ranges needles)
if (Ranges.length > 1 &&
allSatisfy!(isForwardRange, Ranges) &&
size_t canFind(Range, Needles...)(Range haystack, scope Needles needles)
if (Needles.length > 1 &&
is(typeof(find!pred(haystack, needles))))
{
return find!pred(haystack, needles)[1];
@ -2597,6 +2596,13 @@ template canFind(alias pred="a == b")
assert(canFind(arr, [1, 3], [2, 4]) == 0);
}
// More multiple needles
@safe unittest
{
assert([1, 2, 3].canFind(3, 2) == 2);
assert([1, 2, 3].canFind([1, 3], 2) == 2);
}
/**
* Example using a custom predicate.
* Note that the needle appears as the second argument of the predicate.