44#define QUICK_SORT(TYPE, N, A, LESS) \
45 do { \
46 KISSAT_assert (N); \
47 KISSAT_assert (EMPTY_STACK (SORTER)); \
48\
49 size_t L_QUICK_SORT = 0; \
50 size_t R_QUICK_SORT = N - 1; \
51\
52 if (R_QUICK_SORT - L_QUICK_SORT <= QUICK_SORT_LIMIT) \
53 break; \
54\
55 for (;;) { \
56 const size_t M = L_QUICK_SORT + (R_QUICK_SORT - L_QUICK_SORT) / 2; \
57\
58 SWAP (TYPE, A[M], A[R_QUICK_SORT - 1]); \
59\
60 GREATER_SWAP (TYPE, A[L_QUICK_SORT], A[R_QUICK_SORT - 1], LESS); \
61 GREATER_SWAP (TYPE, A[L_QUICK_SORT], A[R_QUICK_SORT], LESS); \
62 GREATER_SWAP (TYPE, A[R_QUICK_SORT - 1], A[R_QUICK_SORT], LESS); \
63\
64 size_t I_QUICK_SORT; \
65\
66 PARTITION (TYPE, L_QUICK_SORT + 1, R_QUICK_SORT - 1, A, LESS); \
67 KISSAT_assert (L_QUICK_SORT < I_QUICK_SORT); \
68 KISSAT_assert (I_QUICK_SORT <= R_QUICK_SORT); \
69\
70 size_t LL_QUICK_SORT; \
71 size_t RR_QUICK_SORT; \
72\
73 if (I_QUICK_SORT - L_QUICK_SORT < R_QUICK_SORT - I_QUICK_SORT) { \
74 LL_QUICK_SORT = I_QUICK_SORT + 1; \
75 RR_QUICK_SORT = R_QUICK_SORT; \
76 R_QUICK_SORT = I_QUICK_SORT - 1; \
77 } else { \
78 LL_QUICK_SORT = L_QUICK_SORT; \
79 RR_QUICK_SORT = I_QUICK_SORT - 1; \
80 L_QUICK_SORT = I_QUICK_SORT + 1; \
81 } \
82 if (R_QUICK_SORT - L_QUICK_SORT > QUICK_SORT_LIMIT) { \
83 KISSAT_assert (RR_QUICK_SORT - LL_QUICK_SORT > QUICK_SORT_LIMIT); \
84 PUSH_STACK (SORTER, LL_QUICK_SORT); \
85 PUSH_STACK (SORTER, RR_QUICK_SORT); \
86 } else if (RR_QUICK_SORT - LL_QUICK_SORT > QUICK_SORT_LIMIT) { \
87 L_QUICK_SORT = LL_QUICK_SORT; \
88 R_QUICK_SORT = RR_QUICK_SORT; \
89 } else if (!EMPTY_STACK (SORTER)) { \
90 R_QUICK_SORT = POP_STACK (SORTER); \
91 L_QUICK_SORT = POP_STACK (SORTER); \
92 } else \
93 break; \
94 } \
95 } while (0)