Acted on comments

This commit is contained in:
Andrei Alexandrescu 2011-09-17 11:57:26 -05:00
parent 9376a49bad
commit c7ee2f5d2d

View file

@ -6368,7 +6368,11 @@ BUGS: stable $(D partition3) has not been implemented yet.
*/
auto partition3(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range, E)
(Range r, E pivot)
if (ss == SwapStrategy.unstable && isRandomAccessRange!Range)
if (ss == SwapStrategy.unstable && isRandomAccessRange!Range
&& hasSwappableElements!Range && hasLength!Range
&& is(typeof(binaryFun!less(r.front, pivot)) == bool)
&& is(typeof(binaryFun!less(pivot, r.front)) == bool)
&& is(typeof(binaryFun!less(r.front, r.front)) == bool))
{
// The algorithm is described in "Engineering a sort function" by
// Jon Bentley et al, pp 1257.
@ -6407,10 +6411,10 @@ auto partition3(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, R
auto swapLen = min(i, strictlyLess);
swapRanges(r[0 .. swapLen], r[j - swapLen .. j]);
swapLen = min(r.length - l, strictlyGreater);
swapRanges(r[k .. k + swapLen], r[$ - swapLen .. $]);
swapRanges(r[k .. k + swapLen], r[r.length - swapLen .. r.length]);
return tuple(r[0 .. strictlyLess],
r[strictlyLess .. $ - strictlyGreater],
r[$ - strictlyGreater .. $]);
r[strictlyLess .. r.length - strictlyGreater],
r[r.length - strictlyGreater .. r.length]);
}
unittest
@ -6717,7 +6721,18 @@ unittest
assert(isSorted!("toUpper(a) < toUpper(b)")(b));
}
/*
private template validPredicates(E, less...) {
static if (less.length == 0)
enum validPredicates = true;
else static if (less.length == 1 && is(typeof(less[0]) == SwapStrategy))
enum validPredicates = true;
else
enum validPredicates =
is(typeof(binaryFun!(less[0])(E.init, E.init)) == bool) &&
validPredicates!(E, less[1 .. $]);
}
/**
Sorts a range by multiple keys. The call $(D multiSort!("a.id < b.id",
"a.date > b.date")(r)) sorts the range $(D r) by $(D id) ascending,
and sorts elements that have the same $(D id) by $(D date)
@ -6737,6 +6752,7 @@ assert(pts1 == pts2);
template multiSort(less...) //if (less.length > 1)
{
void multiSort(Range)(Range r)
if (validPredicates!(ElementType!Range, less))
{
static if (is(typeof(less[$ - 1]) == SwapStrategy))
{
@ -6752,12 +6768,23 @@ template multiSort(less...) //if (less.length > 1)
static if (funs.length > 1)
{
if (r.length <= 1) return;
auto p = getPivot!lessFun(r);
auto t = partition3!(less[0], ss)(r, r[p]);
.multiSort!less(t[0]);
.multiSort!(less[1 .. $])(t[1]);
.multiSort!less(t[2]);
while (r.length > 1)
{
auto p = getPivot!lessFun(r);
auto t = partition3!(less[0], ss)(r, r[p]);
if (t[0].length <= t[2].length)
{
.multiSort!less(t[0]);
.multiSort!(less[1 .. $])(t[1]);
r = t[2];
}
else
{
.multiSort!(less[1 .. $])(t[1]);
.multiSort!less(t[2]);
r = t[0];
}
}
}
else
{
@ -6771,8 +6798,13 @@ unittest
static struct Point { int x, y; }
auto pts1 = [ Point(5, 6), Point(1, 0), Point(5, 7), Point(1, 1), Point(1, 2), Point(0, 1) ];
auto pts2 = [ Point(0, 1), Point(1, 0), Point(1, 1), Point(1, 2), Point(5, 6), Point(5, 7) ];
static assert(validPredicates!(Point, "a.x < b.x", "a.y < b.y"));
multiSort!("a.x < b.x", "a.y < b.y", SwapStrategy.unstable)(pts1);
assert(pts1 == pts2);
auto pts3 = indexed(pts1, iota(pts1.length));
multiSort!("a.x < b.x", "a.y < b.y", SwapStrategy.unstable)(pts3);
assert(equal(pts3, pts2));
}
// @@@BUG1904