Skip to content

Commit b297804

Browse files
authored
Merge pull request #4429 from JackStouffer/issue16170
[Issue 16170] Partial Fix for Broken std.algorithm.sorting.partition
2 parents 3026329 + e21f272 commit b297804

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

std/algorithm/sorting.d

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -389,31 +389,38 @@ See_Also:
389389
STL's $(HTTP sgi.com/tech/stl/_partition.html, _partition)$(BR)
390390
STL's $(HTTP sgi.com/tech/stl/stable_partition.html, stable_partition)
391391
*/
392-
Range partition(alias predicate,
393-
SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)
394-
if ((ss == SwapStrategy.stable && isRandomAccessRange!(Range) && hasLength!Range && hasSlicing!Range)
395-
|| (ss != SwapStrategy.stable && isForwardRange!(Range)))
392+
Range partition(alias predicate, SwapStrategy ss, Range)(Range r)
393+
if (ss == SwapStrategy.stable && isRandomAccessRange!(Range) && hasLength!Range && hasSlicing!Range)
396394
{
395+
import std.algorithm.mutation : bringToFront;
396+
397397
alias pred = unaryFun!(predicate);
398398
if (r.empty) return r;
399-
static if (ss == SwapStrategy.stable)
399+
400+
if (r.length == 1)
400401
{
401-
import std.algorithm.mutation : bringToFront;
402-
if (r.length == 1)
403-
{
404-
if (pred(r.front)) r.popFront();
405-
return r;
406-
}
407-
const middle = r.length / 2;
408-
alias recurse = .partition!(pred, ss, Range);
409-
auto lower = recurse(r[0 .. middle]);
410-
auto upper = recurse(r[middle .. r.length]);
411-
bringToFront(lower, r[middle .. r.length - upper.length]);
412-
return r[r.length - lower.length - upper.length .. r.length];
402+
if (pred(r.front)) r.popFront();
403+
return r;
413404
}
414-
else static if (ss == SwapStrategy.semistable)
405+
const middle = r.length / 2;
406+
alias recurse = .partition!(pred, ss, Range);
407+
auto lower = recurse(r[0 .. middle]);
408+
auto upper = recurse(r[middle .. r.length]);
409+
bringToFront(lower, r[middle .. r.length - upper.length]);
410+
return r[r.length - lower.length - upper.length .. r.length];
411+
}
412+
413+
///ditto
414+
Range partition(alias predicate, SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)
415+
if (ss != SwapStrategy.stable && isInputRange!Range && hasSwappableElements!Range)
416+
{
417+
import std.algorithm.mutation : swap;
418+
alias pred = unaryFun!(predicate);
419+
420+
static if (ss == SwapStrategy.semistable)
415421
{
416-
import std.algorithm.mutation : swap;
422+
if (r.empty) return r;
423+
417424
for (; !r.empty; r.popFront())
418425
{
419426
// skip the initial portion of "correct" elements
@@ -428,9 +435,10 @@ Range partition(alias predicate,
428435
}
429436
return result;
430437
}
438+
431439
return r;
432440
}
433-
else // ss == SwapStrategy.unstable
441+
else
434442
{
435443
// Inspired from www.stepanovpapers.com/PAM3-partition_notes.pdf,
436444
// section "Bidirectional Partition Algorithm (Hoare)"

0 commit comments

Comments
 (0)