Skip to content

Commit 424aec1

Browse files
committed
Fix Issue 16996 - std.algorithm.remove with SwapStrategy.unstable removes more entries
1 parent bb3d78f commit 424aec1

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

std/algorithm/mutation.d

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,8 +1631,6 @@ if (s != SwapStrategy.stable
16311631
&& hasLength!Range
16321632
&& Offset.length >= 1)
16331633
{
1634-
import std.algorithm.comparison : min;
1635-
16361634
Tuple!(size_t, "pos", size_t, "len")[offset.length] blackouts;
16371635
foreach (i, v; offset)
16381636
{
@@ -1659,7 +1657,7 @@ if (s != SwapStrategy.stable
16591657

16601658
size_t left = 0, right = offset.length - 1;
16611659
auto tgt = range.save;
1662-
size_t steps = 0;
1660+
size_t tgtPos = 0;
16631661

16641662
while (left <= right)
16651663
{
@@ -1680,25 +1678,31 @@ if (s != SwapStrategy.stable
16801678
break;
16811679
}
16821680
// Advance to next blackout on the left
1683-
assert(blackouts[left].pos >= steps);
1684-
tgt.popFrontExactly(blackouts[left].pos - steps);
1685-
steps = blackouts[left].pos;
1686-
immutable toMove = min(
1687-
blackouts[left].len,
1688-
range.length - (blackouts[right].pos + blackouts[right].len));
1681+
assert(blackouts[left].pos >= tgtPos);
1682+
tgt.popFrontExactly(blackouts[left].pos - tgtPos);
1683+
tgtPos = blackouts[left].pos;
1684+
1685+
// Number of elements to the right of blackouts[right]
1686+
immutable tailLen = range.length - (blackouts[right].pos + blackouts[right].len);
1687+
size_t toMove = void;
1688+
if (tailLen < blackouts[left].len)
1689+
{
1690+
toMove = tailLen;
1691+
blackouts[left].pos += toMove;
1692+
blackouts[left].len -= toMove;
1693+
}
1694+
else
1695+
{
1696+
toMove = blackouts[left].len;
1697+
++left;
1698+
}
1699+
tgtPos += toMove;
16891700
foreach (i; 0 .. toMove)
16901701
{
16911702
move(range.back, tgt.front);
16921703
range.popBack();
16931704
tgt.popFront();
16941705
}
1695-
steps += toMove;
1696-
if (toMove == blackouts[left].len)
1697-
{
1698-
// Filled the entire left hole
1699-
++left;
1700-
continue;
1701-
}
17021706
}
17031707

17041708
return range;
@@ -1770,7 +1774,7 @@ if (s == SwapStrategy.stable
17701774
a = [ 0, 1, 2, 3, 4, 5 ];
17711775
assert(remove!(SwapStrategy.unstable)(a, 1) == [0, 5, 2, 3, 4]);
17721776
a = [ 0, 1, 2, 3, 4, 5 ];
1773-
assert(remove!(SwapStrategy.unstable)(a, tuple(1, 4)) == [0]);
1777+
assert(remove!(SwapStrategy.unstable)(a, tuple(1, 4)) == [0, 5, 4]);
17741778
}
17751779

17761780
@safe unittest

0 commit comments

Comments
 (0)