mirror of
https://github.com/dlang/phobos.git
synced 2025-05-02 08:00:48 +03:00
Merge pull request #1166 from andralex/5507
Fix Issue 5507 - countUntil should take Ranges... instead of R2
This commit is contained in:
commit
54ddafa1a8
1 changed files with 81 additions and 32 deletions
|
@ -4399,11 +4399,11 @@ unittest
|
||||||
/++
|
/++
|
||||||
Returns the number of elements which must be popped from the front of
|
Returns the number of elements which must be popped from the front of
|
||||||
$(D haystack) before reaching an element for which
|
$(D haystack) before reaching an element for which
|
||||||
$(D startsWith!pred(haystack, needle)) is $(D true). If
|
$(D startsWith!pred(haystack, needles)) is $(D true). If
|
||||||
$(D startsWith!pred(haystack, needle)) is not $(D true) for any element in
|
$(D startsWith!pred(haystack, needles)) is not $(D true) for any element in
|
||||||
$(D haystack), then -1 is returned.
|
$(D haystack), then $(D -1) is returned.
|
||||||
|
|
||||||
$(D needle) may be either an element or a range.
|
$(D needles) may be either an element or a range.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -4419,23 +4419,30 @@ assert(countUntil([0, 7, 12, 22, 9], 9) == 4);
|
||||||
assert(countUntil!"a > b"([0, 7, 12, 22, 9], 20) == 3);
|
assert(countUntil!"a > b"([0, 7, 12, 22, 9], 20) == 3);
|
||||||
--------------------
|
--------------------
|
||||||
+/
|
+/
|
||||||
ptrdiff_t countUntil(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles)
|
||||||
if (isForwardRange!R1 && isForwardRange!R2 &&
|
if (isForwardRange!R
|
||||||
is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
|
&& Rs.length > 0
|
||||||
|
&& isForwardRange!(Rs[0]) == isInputRange!(Rs[0])
|
||||||
|
&& is(typeof(startsWith!pred(haystack, needles[0])))
|
||||||
|
&& (Rs.length == 1
|
||||||
|
|| is(typeof(countUntil!pred(haystack, needles[1 .. $])))))
|
||||||
{
|
{
|
||||||
typeof(return) result;
|
typeof(return) result;
|
||||||
static if (hasLength!R1) //Note: Narrow strings don't have length.
|
|
||||||
|
static if (needles.length == 1)
|
||||||
|
{
|
||||||
|
static if (hasLength!R) //Note: Narrow strings don't have length.
|
||||||
{
|
{
|
||||||
//We delegate to find because find is very efficient.
|
//We delegate to find because find is very efficient.
|
||||||
//We store the length of the haystack so we don't have to save it.
|
//We store the length of the haystack so we don't have to save it.
|
||||||
auto len = haystack.length;
|
auto len = haystack.length;
|
||||||
auto r2 = find!pred(haystack, needle);
|
auto r2 = find!pred(haystack, needles[0]);
|
||||||
if (!r2.empty)
|
if (!r2.empty)
|
||||||
return cast(typeof(return)) (len - r2.length);
|
return cast(typeof(return)) (len - r2.length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (needle.empty)
|
if (needles[0].empty)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//Default case, slower route doing startsWith iteration
|
//Default case, slower route doing startsWith iteration
|
||||||
|
@ -4445,21 +4452,55 @@ ptrdiff_t countUntil(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||||
//forwarding to startsWith. This avoids making useless saves to
|
//forwarding to startsWith. This avoids making useless saves to
|
||||||
//haystack/needle if they aren't even going to be mutated anyways.
|
//haystack/needle if they aren't even going to be mutated anyways.
|
||||||
//It also cuts down on the amount of pops on haystack.
|
//It also cuts down on the amount of pops on haystack.
|
||||||
if (binaryFun!pred(haystack.front, needle.front))
|
if (binaryFun!pred(haystack.front, needles[0].front))
|
||||||
{
|
{
|
||||||
//Here, we need to save the needle before popping it.
|
//Here, we need to save the needle before popping it.
|
||||||
//haystack we pop in all paths, so we do that, and then save.
|
//haystack we pop in all paths, so we do that, and then save.
|
||||||
haystack.popFront();
|
haystack.popFront();
|
||||||
if (startsWith!pred(haystack.save, needle.save.dropOne()))
|
if (startsWith!pred(haystack.save, needles[0].save.dropOne()))
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
haystack.popFront();
|
haystack.popFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (i, Ri; Rs)
|
||||||
|
{
|
||||||
|
static if (isForwardRange!Ri)
|
||||||
|
{
|
||||||
|
if (needles[i].empty)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tuple!Rs t;
|
||||||
|
foreach (i, Ri; Rs)
|
||||||
|
{
|
||||||
|
static if (!isForwardRange!Ri)
|
||||||
|
{
|
||||||
|
t[i] = needles[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; !haystack.empty ; ++result, haystack.popFront())
|
||||||
|
{
|
||||||
|
foreach (i, Ri; Rs)
|
||||||
|
{
|
||||||
|
static if (isForwardRange!Ri)
|
||||||
|
{
|
||||||
|
t[i] = needles[i].save;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (startsWith!pred(haystack.save, t.expand))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Because of @@@8804@@@: Avoids both "unreachable code" or "no return statement"
|
//Because of @@@8804@@@: Avoids both "unreachable code" or "no return statement"
|
||||||
static if (isInfinite!R1) assert(0);
|
static if (isInfinite!R) assert(0);
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
/// ditto
|
/// ditto
|
||||||
|
@ -4509,6 +4550,14 @@ unittest
|
||||||
assert(r.save.countUntil(r3) == -1);
|
assert(r.save.countUntil(r3) == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
assert(countUntil("hello world", "world", "asd") == 6);
|
||||||
|
assert(countUntil("hello world", "world", "ello") == 1);
|
||||||
|
assert(countUntil("hello world", "world", "") == 0);
|
||||||
|
assert(countUntil("hello world", "world", 'l') == 2);
|
||||||
|
}
|
||||||
|
|
||||||
/++
|
/++
|
||||||
Returns the number of elements which must be popped from $(D haystack)
|
Returns the number of elements which must be popped from $(D haystack)
|
||||||
before $(D pred(haystack.front)) is $(D true).
|
before $(D pred(haystack.front)) is $(D true).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue