11#error "Must declare SORT_NAME"
15#error "Must declare SORT_TYPE"
19#define SORT_CMP(x, y) ((x) < (y) ? -1 : ((y) < (x) ? 1 : 0))
27#pragma GCC diagnostic push
28#pragma GCC diagnostic ignored "-Wunused-function"
34#define SORT_SAFE_CPY 0
38#define SORT_SAFE_CPY 0
41#ifndef TIM_SORT_STACK_SIZE
42#define TIM_SORT_STACK_SIZE 128
46#define SORT_SWAP(x,y) {SORT_TYPE _sort_swap_temp = (x); (x) = (y); (y) = _sort_swap_temp;}
54#define MAX(x,y) (((x) > (y) ? (x) : (y)))
58#define MIN(x,y) (((x) < (y) ? (x) : (y)))
61static int compute_minrun(
const uint64_t);
64static const uint64_t shell_gaps[48] = {1, 4, 10, 23, 57, 132, 301, 701, 1750, 4376, 10941, 27353, 68383, 170958, 427396, 1068491, 2671228, 6678071, 16695178, 41737946, 104344866, 260862166, 652155416, 1630388541, 4075971353LL, 10189928383LL, 25474820958LL, 63687052396LL, 159217630991LL, 398044077478LL, 995110193696LL, 2487775484241LL, 6219438710603LL, 15548596776508LL, 38871491941271LL, 97178729853178LL, 242946824632946LL, 607367061582366LL, 1518417653955916LL, 3796044134889791LL, 9490110337224478LL, 23725275843061196LL, 59313189607652991LL, 148282974019132478LL, 370707435047831196LL, 926768587619577991LL, 2316921469048944978LL, 5792303672622362446LL};
69#define __has_builtin(x) 0
71#if __has_builtin(__builtin_clzll) || (defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ > 3)))
72#define CLZ __builtin_clzll
75static int clzll(uint64_t);
78static int clzll(uint64_t x) {
87 if (x <= 0x00000000FFFFFFFFL) {
92 if (x <= 0x0000FFFFFFFFFFFFL) {
97 if (x <= 0x00FFFFFFFFFFFFFFL) {
102 if (x <= 0x0FFFFFFFFFFFFFFFL) {
107 if (x <= 0x3FFFFFFFFFFFFFFFL) {
112 if (x <= 0x7FFFFFFFFFFFFFFFL) {
123static __inline
int compute_minrun(
const uint64_t size) {
124 const int top_bit = 64 -
CLZ(size);
125 const int shift =
MAX(top_bit, 6) - 6;
126 const int minrun = (int)(size >> shift);
127 const uint64_t mask = (1ULL << shift) - 1;
136static __inline
size_t rbnd(
size_t len) {
144 return 1ULL << ((2 * k) / 3);
149#define SORT_CONCAT(x, y) x ## _ ## y
150#define SORT_MAKE_STR1(x, y) SORT_CONCAT(x,y)
151#define SORT_MAKE_STR(x) SORT_MAKE_STR1(SORT_NAME,x)
153#ifndef SMALL_SORT_BND
154#define SMALL_SORT_BND 16
157#define SMALL_SORT BITONIC_SORT
160#ifndef SMALL_STABLE_SORT
161#define SMALL_STABLE_SORT BINARY_INSERTION_SORT
164#define SORT_TYPE_CPY SORT_MAKE_STR(sort_type_cpy)
165#define SORT_TYPE_MOVE SORT_MAKE_STR(sort_type_move)
166#define SORT_NEW_BUFFER SORT_MAKE_STR(sort_new_buffer)
167#define SORT_DELETE_BUFFER SORT_MAKE_STR(sort_delete_buffer)
168#define BITONIC_SORT SORT_MAKE_STR(bitonic_sort)
169#define BINARY_INSERTION_FIND SORT_MAKE_STR(binary_insertion_find)
170#define BINARY_INSERTION_SORT_START SORT_MAKE_STR(binary_insertion_sort_start)
171#define BINARY_INSERTION_SORT SORT_MAKE_STR(binary_insertion_sort)
172#define REVERSE_ELEMENTS SORT_MAKE_STR(reverse_elements)
173#define COUNT_RUN SORT_MAKE_STR(count_run)
174#define CHECK_INVARIANT SORT_MAKE_STR(check_invariant)
175#define TIM_SORT SORT_MAKE_STR(tim_sort)
176#define TIM_SORT_RESIZE SORT_MAKE_STR(tim_sort_resize)
177#define TIM_SORT_MERGE SORT_MAKE_STR(tim_sort_merge)
178#define TIM_SORT_COLLAPSE SORT_MAKE_STR(tim_sort_collapse)
179#define HEAP_SORT SORT_MAKE_STR(heap_sort)
180#define MEDIAN SORT_MAKE_STR(median)
181#define QUICK_SORT SORT_MAKE_STR(quick_sort)
182#define MERGE_SORT SORT_MAKE_STR(merge_sort)
183#define MERGE_SORT_RECURSIVE SORT_MAKE_STR(merge_sort_recursive)
184#define MERGE_SORT_IN_PLACE SORT_MAKE_STR(merge_sort_in_place)
185#define MERGE_SORT_IN_PLACE_RMERGE SORT_MAKE_STR(merge_sort_in_place_rmerge)
186#define MERGE_SORT_IN_PLACE_BACKMERGE SORT_MAKE_STR(merge_sort_in_place_backmerge)
187#define MERGE_SORT_IN_PLACE_FRONTMERGE SORT_MAKE_STR(merge_sort_in_place_frontmerge)
188#define MERGE_SORT_IN_PLACE_ASWAP SORT_MAKE_STR(merge_sort_in_place_aswap)
189#define SHELL_SORT SORT_MAKE_STR(shell_sort)
190#define QUICK_SORT_PARTITION SORT_MAKE_STR(quick_sort_partition)
191#define QUICK_SORT_RECURSIVE SORT_MAKE_STR(quick_sort_recursive)
192#define HEAP_SIFT_DOWN SORT_MAKE_STR(heap_sift_down)
193#define HEAPIFY SORT_MAKE_STR(heapify)
194#define TIM_SORT_RUN_T SORT_MAKE_STR(tim_sort_run_t)
195#define TEMP_STORAGE_T SORT_MAKE_STR(temp_storage_t)
196#define PUSH_NEXT SORT_MAKE_STR(push_next)
199#define MAX(x,y) (((x) > (y) ? (x) : (y)))
202#define MIN(x,y) (((x) < (y) ? (x) : (y)))
205#define SORT_CSWAP(x, y) { if(SORT_CMP((x),(y)) > 0) {SORT_SWAP((x),(y));}}
229#define BITONIC_SORT_2 SORT_MAKE_STR(bitonic_sort_2)
235#define BITONIC_SORT_3 SORT_MAKE_STR(bitonic_sort_3)
243#define BITONIC_SORT_4 SORT_MAKE_STR(bitonic_sort_4)
253#define BITONIC_SORT_5 SORT_MAKE_STR(bitonic_sort_5)
267#define BITONIC_SORT_6 SORT_MAKE_STR(bitonic_sort_6)
284#define BITONIC_SORT_7 SORT_MAKE_STR(bitonic_sort_7)
305#define BITONIC_SORT_8 SORT_MAKE_STR(bitonic_sort_8)
329#define BITONIC_SORT_9 SORT_MAKE_STR(bitonic_sort_9)
359#define BITONIC_SORT_10 SORT_MAKE_STR(bitonic_sort_10)
393#define BITONIC_SORT_11 SORT_MAKE_STR(bitonic_sort_11)
433#define BITONIC_SORT_12 SORT_MAKE_STR(bitonic_sort_12)
477#define BITONIC_SORT_13 SORT_MAKE_STR(bitonic_sort_13)
527#define BITONIC_SORT_14 SORT_MAKE_STR(bitonic_sort_14)
583#define BITONIC_SORT_15 SORT_MAKE_STR(bitonic_sort_15)
644#define BITONIC_SORT_16 SORT_MAKE_STR(bitonic_sort_16)
784 for (; i < size; ++i) {
794 }
else if (dst != src && size > 0) {
795 for (i = size - 1; i > 0; --i) {
806#define SORT_TYPE_CPY(dst, src, size) memcpy((dst), (src), (size) * sizeof(SORT_TYPE))
808#define SORT_TYPE_MOVE(dst, src, size) memmove((dst), (src), (size) * sizeof(SORT_TYPE))
836 size_t inc = shell_gaps[inci];
843 while (inc > (size >> 1)) {
844 inc = shell_gaps[--inci];
848 for (i = inc; i < size; i++) {
852 while ((j >= inc) && (
SORT_CMP(dst[j - inc], temp) > 0)) {
853 dst[j] = dst[j - inc];
864 inc = shell_gaps[--inci];
880 }
else if (
SORT_CMP(x, dst[r]) > 0) {
903 c = l + ((r - l) >> 1);
912 for (i = start; i < size; i++) {
918 if (
SORT_CMP(dst[i - 1], dst[i]) <= 0) {
926 for (j = i - 1; j >= location; j--) {
961 if (
SORT_CMP(dst1[l1 - 1], dst2[0]) <= 0) {
967 while (
SORT_CMP(*dst2, *dst1) > 0) {
994 if (
SORT_CMP(dst1[1 - l1], dst2[0]) >= 0) {
1000 while (
SORT_CMP(*dst2, *dst1) < 0) {
1031 if (
SORT_CMP(dst[lp], dst[lp - 1]) >= 0) {
1037 for (i = 0; i < len; i += r) {
1041 for (j = lp; j <= lq; j += r) {
1045 cv =
SORT_CMP(dst[j + r - 1], dst[q + r - 1]);
1056 if (q == lq && q < (len - r)) {
1061 if (i != 0 &&
SORT_CMP(dst[i], dst[i - 1]) < 0) {
1076 size_t r = rbnd(len);
1077 size_t lr = (len / r - 1) * r;
1079 size_t p, m, q, q1, p0;
1090 for (
p = 2;
p <= lr;
p += 2) {
1093 if (
SORT_CMP(dst1[0], dst1[-1]) < 0) {
1104 while ((
p & q) == 0) {
1105 if (
SORT_CMP(dst1[1 - q], dst1[-(
int) q]) < 0) {
1123 if ((q1 > m) || (
p & q1)) {
1142 while ((q &
p) == 0) {
1150 for (q = r; q < lr; q *= 2) {
1151 if ((lr & q) != 0) {
1169 const size_t middle = size / 2;
1187 while (out != size) {
1190 if (
SORT_CMP(dst[i], dst[j]) <= 0) {
1191 newdst[out] = dst[i++];
1193 newdst[out] = dst[j++];
1196 newdst[out] = dst[i++];
1199 newdst[out] = dst[j++];
1229 const size_t right,
const size_t pivot) {
1231 size_t index = left;
1233 int not_all_same = 0;
1237 for (i = left; i < right; i++) {
1240 not_all_same |= cmp;
1251 if (not_all_same == 0) {
1291static __inline
size_t MEDIAN(
const SORT_TYPE *dst,
const size_t a,
const size_t b,
1293 const int AB =
SORT_CMP(dst[a], dst[b]) < 0;
1297 const int BC =
SORT_CMP(dst[b], dst[c]) < 0;
1304 const int AC =
SORT_CMP(dst[a], dst[c]) < 0;
1316 const int AC =
SORT_CMP(dst[a], dst[b]) < 0;
1323 const int BC =
SORT_CMP(dst[b], dst[c]) < 0;
1337 const size_t original_right) {
1344 const int max_loops = 64 -
CLZ(original_right - original_left);
1345 left = original_left;
1346 right = original_right;
1349 if (right <= left) {
1358 if (++loop_count >= max_loops) {
1360 HEAP_SORT(&dst[left], right - left + 1U);
1365 middle = left + ((right - left) >> 1);
1367 pivot =
MEDIAN((
const SORT_TYPE *) dst, left + ((middle - left) >> 1), pivot,
1368 middle + ((right - middle) >> 1));
1372 if (new_pivot == SIZE_MAX) {
1378 if (new_pivot - 1U - left > right - new_pivot - 1U) {
1382 right = new_pivot - 1U;
1387 left = new_pivot + 1U;
1419 if (size - start == 1) {
1423 if (start >= size - 2) {
1424 if (
SORT_CMP(dst[size - 2], dst[size - 1]) > 0) {
1425 SORT_SWAP(dst[size - 2], dst[size - 1]);
1433 if (
SORT_CMP(dst[start], dst[start + 1]) <= 0) {
1436 if (curr == size - 1) {
1440 if (
SORT_CMP(dst[curr - 1], dst[curr]) > 0) {
1447 return curr - start;
1451 if (curr == size - 1) {
1455 if (
SORT_CMP(dst[curr - 1], dst[curr]) <= 0) {
1464 return curr - start;
1471 if (stack_curr < 2) {
1475 if (stack_curr == 2) {
1476 const size_t A1 = stack[stack_curr - 2].
length;
1477 const size_t B1 = stack[stack_curr - 1].
length;
1486 A = stack[stack_curr - 3].
length;
1487 B = stack[stack_curr - 2].
length;
1488 C = stack[stack_curr - 1].
length;
1490 if ((A <= B + C) || (B <= C)) {
1503 if ((store->
storage == NULL) || (store->
alloc < new_size)) {
1506 if (tempstore == NULL) {
1507 fprintf(stderr,
"Error allocating temporary storage for tim sort: need %lu bytes",
1508 (
unsigned long)(
sizeof(
SORT_TYPE) * new_size));
1513 store->
alloc = new_size;
1519 const size_t A = stack[stack_curr - 2].
length;
1520 const size_t B = stack[stack_curr - 1].
length;
1521 const size_t curr = stack[stack_curr - 2].
start;
1533 for (k = curr; k < curr + A + B; k++) {
1534 if ((i < A) && (j < curr + A + B)) {
1535 if (
SORT_CMP(storage[i], dst[j]) <= 0) {
1536 dst[k] = storage[i++];
1541 dst[k] = storage[i++];
1553 while (k-- > curr) {
1554 if ((i > 0) && (j > curr)) {
1555 if (
SORT_CMP(dst[j - 1], storage[i - 1]) > 0) {
1558 dst[k] = storage[--i];
1561 dst[k] = storage[--i];
1576 if (stack_curr <= 1) {
1581 if ((stack_curr == 2) && (stack[0].length + stack[1].length == size)) {
1588 else if ((stack_curr == 2) && (stack[0].length <= stack[1].length)) {
1593 }
else if (stack_curr == 2) {
1597 B = stack[stack_curr - 3].
length;
1598 C = stack[stack_curr - 2].
length;
1599 D = stack[stack_curr - 1].
length;
1601 if (stack_curr >= 4) {
1602 A = stack[stack_curr - 4].
length;
1608 BCD = (B <= C + D) || ABC;
1619 stack[stack_curr - 3].
length += stack[stack_curr - 2].
length;
1620 stack[stack_curr - 2] = stack[stack_curr - 1];
1625 stack[stack_curr - 2].
length += stack[stack_curr - 1].
length;
1636 const size_t minrun,
1640 size_t len =
COUNT_RUN(dst, *curr, size);
1641 size_t run = minrun;
1643 if (run > size - *curr) {
1652 run_stack[*stack_curr].
start = *curr;
1653 run_stack[*stack_curr].
length = len;
1657 if (*curr == size) {
1659 while (*stack_curr > 1) {
1661 run_stack[*stack_curr - 2].
length += run_stack[*stack_curr - 1].
length;
1680 size_t stack_curr = 0;
1694 minrun = compute_minrun(size);
1700 if (!
PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
1704 if (!
PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
1708 if (!
PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
1718 if (!
PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
1727 size_t root = start;
1729 while ((root << 1) <= end) {
1730 size_t child = root << 1;
1732 if ((child < end) && (
SORT_CMP(dst[child], dst[child + 1]) < 0)) {
1736 if (
SORT_CMP(dst[root], dst[child]) < 0) {
1746 size_t start = size >> 1;
1760 size_t end = size - 1;
1777#include "sort_extra.h"
1782#undef SORT_TYPE_MOVE
1783#undef SORT_NEW_BUFFER
1784#undef SORT_DELETE_BUFFER
1788#undef SORT_MAKE_STR1
1793#undef TEMP_STORAGE_T
1794#undef TIM_SORT_RUN_T
1797#undef SORT_MAKE_STR1
1799#undef BINARY_INSERTION_FIND
1800#undef BINARY_INSERTION_SORT_START
1801#undef BINARY_INSERTION_SORT
1802#undef REVERSE_ELEMENTS
1805#undef TIM_SORT_RESIZE
1806#undef TIM_SORT_COLLAPSE
1807#undef TIM_SORT_RUN_T
1808#undef TEMP_STORAGE_T
1810#undef MERGE_SORT_RECURSIVE
1811#undef MERGE_SORT_IN_PLACE
1812#undef MERGE_SORT_IN_PLACE_RMERGE
1813#undef MERGE_SORT_IN_PLACE_BACKMERGE
1814#undef MERGE_SORT_IN_PLACE_FRONTMERGE
1815#undef MERGE_SORT_IN_PLACE_ASWAP
1819#pragma GCC diagnostic pop
#define BINARY_INSERTION_SORT_START
#define QUICK_SORT_RECURSIVE
#define TIM_SORT_COLLAPSE
#define MERGE_SORT_RECURSIVE
#define SMALL_STABLE_SORT
#define MERGE_SORT_IN_PLACE
#define MERGE_SORT_IN_PLACE_RMERGE
#define QUICK_SORT_PARTITION
#define TIM_SORT_STACK_SIZE
#define SORT_DELETE_BUFFER
#define BINARY_INSERTION_SORT
#define MERGE_SORT_IN_PLACE_BACKMERGE
#define MERGE_SORT_IN_PLACE_ASWAP
#define MERGE_SORT_IN_PLACE_FRONTMERGE
#define BINARY_INSERTION_FIND