227 typedef typename std::iterator_traits<Iter>::value_type T;
236 while (comp(*++first, pivot))
241 if (first - 1 == begin)
242 while (first < last && !comp(*--last, pivot))
245 while (!comp(*--last, pivot))
250 bool already_partitioned = first >= last;
251 if (!already_partitioned) {
252 std::iter_swap(first, last);
263 Iter offsets_l_base = first;
264 Iter offsets_r_base = last;
265 size_t num_l, num_r, start_l, start_r;
266 num_l = num_r = start_l = start_r = 0;
268 while (first < last) {
271 size_t num_unknown = last - first;
272 size_t left_split = num_l == 0 ? (num_r == 0 ? num_unknown / 2 : num_unknown) : 0;
273 size_t right_split = num_r == 0 ? (num_unknown - left_split) : 0;
278 offsets_l[num_l] = (
unsigned char)i++;
279 num_l += !comp(*first, pivot);
281 offsets_l[num_l] = (
unsigned char)i++;
282 num_l += !comp(*first, pivot);
284 offsets_l[num_l] = (
unsigned char)i++;
285 num_l += !comp(*first, pivot);
287 offsets_l[num_l] = (
unsigned char)i++;
288 num_l += !comp(*first, pivot);
290 offsets_l[num_l] = (
unsigned char)i++;
291 num_l += !comp(*first, pivot);
293 offsets_l[num_l] = (
unsigned char)i++;
294 num_l += !comp(*first, pivot);
296 offsets_l[num_l] = (
unsigned char)i++;
297 num_l += !comp(*first, pivot);
299 offsets_l[num_l] = (
unsigned char)i++;
300 num_l += !comp(*first, pivot);
305 for (
size_t i = 0; i < left_split;) {
306 offsets_l[num_l] = (
unsigned char)i++;
307 num_l += !comp(*first, pivot);
314 offsets_r[num_r] = (
unsigned char)++i;
315 num_r += comp(*--last, pivot);
316 offsets_r[num_r] = (
unsigned char)++i;
317 num_r += comp(*--last, pivot);
318 offsets_r[num_r] = (
unsigned char)++i;
319 num_r += comp(*--last, pivot);
320 offsets_r[num_r] = (
unsigned char)++i;
321 num_r += comp(*--last, pivot);
322 offsets_r[num_r] = (
unsigned char)++i;
323 num_r += comp(*--last, pivot);
324 offsets_r[num_r] = (
unsigned char)++i;
325 num_r += comp(*--last, pivot);
326 offsets_r[num_r] = (
unsigned char)++i;
327 num_r += comp(*--last, pivot);
328 offsets_r[num_r] = (
unsigned char)++i;
329 num_r += comp(*--last, pivot);
333 for (
size_t i = 0; i < right_split;) {
334 offsets_r[num_r] = (
unsigned char)++i;
335 num_r += comp(*--last, pivot);
340 size_t num = std::min(num_l, num_r);
341 swap_offsets(offsets_l_base, offsets_r_base, offsets_l + start_l, offsets_r + start_r, num,
350 offsets_l_base = first;
355 offsets_r_base = last;
361 offsets_l += start_l;
363 std::iter_swap(offsets_l_base + offsets_l[num_l], --last);
367 offsets_r += start_r;
369 std::iter_swap(offsets_r_base - offsets_r[num_r], first), ++first;
375 Iter pivot_pos = first - 1;
379 return std::make_pair(pivot_pos, already_partitioned);
390 typedef typename std::iterator_traits<Iter>::value_type T;
400 while (comp(*++first, pivot))
405 if (first - 1 == begin)
406 while (first < last && !comp(*--last, pivot))
409 while (!comp(*--last, pivot))
414 bool already_partitioned = first >= last;
419 while (first < last) {
420 std::iter_swap(first, last);
421 while (comp(*++first, pivot))
423 while (!comp(*--last, pivot))
428 Iter pivot_pos = first - 1;
432 return std::make_pair(pivot_pos, already_partitioned);
474 inline void pdqsort_loop(Iter begin, Iter end, Compare comp,
int bad_allowed,
475 bool leftmost =
true)
477 typedef typename std::iterator_traits<Iter>::difference_type diff_t;
481 diff_t size = end - begin;
493 diff_t s2 = size / 2;
495 sort3(begin, begin + s2, end - 1, comp);
496 sort3(begin + 1, begin + (s2 - 1), end - 2, comp);
497 sort3(begin + 2, begin + (s2 + 1), end - 3, comp);
498 sort3(begin + (s2 - 1), begin + s2, begin + (s2 + 1), comp);
499 std::iter_swap(begin, begin + s2);
502 sort3(begin + s2, begin, end - 1, comp);
509 if (!leftmost && !comp(*(begin - 1), *begin)) {
517 Iter pivot_pos = part_result.first;
518 bool already_partitioned = part_result.second;
521 diff_t l_size = pivot_pos - begin;
522 diff_t r_size = end - (pivot_pos + 1);
523 bool highly_unbalanced = l_size < size / 8 || r_size < size / 8;
526 if (highly_unbalanced) {
528 if (--bad_allowed == 0) {
529 std::make_heap(begin, end, comp);
530 std::sort_heap(begin, end, comp);
535 std::iter_swap(begin, begin + l_size / 4);
536 std::iter_swap(pivot_pos - 1, pivot_pos - l_size / 4);
539 std::iter_swap(begin + 1, begin + (l_size / 4 + 1));
540 std::iter_swap(begin + 2, begin + (l_size / 4 + 2));
541 std::iter_swap(pivot_pos - 2, pivot_pos - (l_size / 4 + 1));
542 std::iter_swap(pivot_pos - 3, pivot_pos - (l_size / 4 + 2));
547 std::iter_swap(pivot_pos + 1, pivot_pos + (1 + r_size / 4));
548 std::iter_swap(end - 1, end - r_size / 4);
551 std::iter_swap(pivot_pos + 2, pivot_pos + (2 + r_size / 4));
552 std::iter_swap(pivot_pos + 3, pivot_pos + (3 + r_size / 4));
553 std::iter_swap(end - 2, end - (1 + r_size / 4));
554 std::iter_swap(end - 3, end - (2 + r_size / 4));
569 begin = pivot_pos + 1;