std.algorithm.remove: Fix constraints and change popBack loop to popBackN

This commit is contained in:
safety0ff 2014-06-17 17:53:15 -04:00
parent 8221ed4c4b
commit 93068b15bd

View file

@ -8527,23 +8527,25 @@ movement to be done which improves the execution time of the function.
The function $(D remove) works on any forward range. The moving The function $(D remove) works on any forward range. The moving
strategy is (listed from fastest to slowest): $(UL $(LI If $(D s == strategy is (listed from fastest to slowest): $(UL $(LI If $(D s ==
SwapStrategy.unstable && isRandomAccessRange!Range && SwapStrategy.unstable && isRandomAccessRange!Range && hasLength!Range
hasLength!Range), then elements are moved from the end of the range && hasLvalueElements!Range), then elements are moved from the end
into the slots to be filled. In this case, the absolute minimum of of the range into the slots to be filled. In this case, the absolute
moves is performed.) $(LI Otherwise, if $(D s == minimum of moves is performed.) $(LI Otherwise, if $(D s ==
SwapStrategy.unstable && isBidirectionalRange!Range && SwapStrategy.unstable && isBidirectionalRange!Range && hasLength!Range
hasLength!Range), then elements are still moved from the end of the && hasLvalueElements!Range), then elements are still moved from the
range, but time is spent on advancing between slots by repeated calls end of the range, but time is spent on advancing between slots by repeated
to $(D range.popFront).) $(LI Otherwise, elements are moved incrementally calls to $(D range.popFront).) $(LI Otherwise, elements are moved
towards the front of $(D range); a given element is never moved incrementally towards the front of $(D range); a given element is never
several times, but more elements are moved than in the previous moved several times, but more elements are moved than in the previous
cases.)) cases.))
*/ */
Range remove Range remove
(SwapStrategy s = SwapStrategy.stable, Range, Offset...) (SwapStrategy s = SwapStrategy.stable, Range, Offset...)
(Range range, Offset offset) (Range range, Offset offset)
if (s != SwapStrategy.stable if (s != SwapStrategy.stable
&& isBidirectionalRange!Range && hasLength!Range && isBidirectionalRange!Range
&& hasLvalueElements!Range
&& hasLength!Range
&& Offset.length >= 1) && Offset.length >= 1)
{ {
Tuple!(size_t, "pos", size_t, "len")[offset.length] blackouts; Tuple!(size_t, "pos", size_t, "len")[offset.length] blackouts;
@ -8621,7 +8623,10 @@ if (s != SwapStrategy.stable
Range remove Range remove
(SwapStrategy s = SwapStrategy.stable, Range, Offset...) (SwapStrategy s = SwapStrategy.stable, Range, Offset...)
(Range range, Offset offset) (Range range, Offset offset)
if (s == SwapStrategy.stable && isForwardRange!Range && Offset.length >= 1) if (s == SwapStrategy.stable
&& isBidirectionalRange!Range
&& hasLvalueElements!Range
&& Offset.length >= 1)
{ {
import std.exception : enforce; import std.exception : enforce;
@ -8656,8 +8661,8 @@ if (s == SwapStrategy.stable && isForwardRange!Range && Offset.length >= 1)
} }
// now skip source to the "to" position // now skip source to the "to" position
src.popFrontN(delta); src.popFrontN(delta);
result.popBackN(delta);
pos += delta; pos += delta;
foreach (j; 0 .. delta) result.popBack();
} }
// leftover move // leftover move
moveAll(src, tgt); moveAll(src, tgt);
@ -8751,7 +8756,8 @@ order is preserved. Returns the filtered range.
*/ */
Range remove(alias pred, SwapStrategy s = SwapStrategy.stable, Range) Range remove(alias pred, SwapStrategy s = SwapStrategy.stable, Range)
(Range range) (Range range)
if (isBidirectionalRange!Range) if (isBidirectionalRange!Range
&& hasLvalueElements!Range)
{ {
auto result = range; auto result = range;
static if (s != SwapStrategy.stable) static if (s != SwapStrategy.stable)