xref: /aosp_15_r20/external/libxml2/timsort.h (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker  * Taken from https://github.com/swenson/sort
3*7c568831SAndroid Build Coastguard Worker  * Revision: 05fd77bfec049ce8b7c408c4d3dd2d51ee061a15
4*7c568831SAndroid Build Coastguard Worker  * Removed all code unrelated to Timsort and made minor adjustments for
5*7c568831SAndroid Build Coastguard Worker  * cross-platform compatibility.
6*7c568831SAndroid Build Coastguard Worker  */
7*7c568831SAndroid Build Coastguard Worker 
8*7c568831SAndroid Build Coastguard Worker /*
9*7c568831SAndroid Build Coastguard Worker  * The MIT License (MIT)
10*7c568831SAndroid Build Coastguard Worker  *
11*7c568831SAndroid Build Coastguard Worker  * Copyright (c) 2010-2017 Christopher Swenson.
12*7c568831SAndroid Build Coastguard Worker  * Copyright (c) 2012 Vojtech Fried.
13*7c568831SAndroid Build Coastguard Worker  * Copyright (c) 2012 Google Inc. All Rights Reserved.
14*7c568831SAndroid Build Coastguard Worker  *
15*7c568831SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
16*7c568831SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
17*7c568831SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
18*7c568831SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19*7c568831SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
20*7c568831SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
21*7c568831SAndroid Build Coastguard Worker  *
22*7c568831SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
23*7c568831SAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
24*7c568831SAndroid Build Coastguard Worker  *
25*7c568831SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26*7c568831SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27*7c568831SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28*7c568831SAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29*7c568831SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30*7c568831SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31*7c568831SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
32*7c568831SAndroid Build Coastguard Worker  */
33*7c568831SAndroid Build Coastguard Worker 
34*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
35*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
36*7c568831SAndroid Build Coastguard Worker #include <string.h>
37*7c568831SAndroid Build Coastguard Worker #ifdef HAVE_STDINT_H
38*7c568831SAndroid Build Coastguard Worker #include <stdint.h>
39*7c568831SAndroid Build Coastguard Worker #elif defined(_WIN32)
40*7c568831SAndroid Build Coastguard Worker typedef unsigned __int64 uint64_t;
41*7c568831SAndroid Build Coastguard Worker #endif
42*7c568831SAndroid Build Coastguard Worker 
43*7c568831SAndroid Build Coastguard Worker #ifndef SORT_NAME
44*7c568831SAndroid Build Coastguard Worker #error "Must declare SORT_NAME"
45*7c568831SAndroid Build Coastguard Worker #endif
46*7c568831SAndroid Build Coastguard Worker 
47*7c568831SAndroid Build Coastguard Worker #ifndef SORT_TYPE
48*7c568831SAndroid Build Coastguard Worker #error "Must declare SORT_TYPE"
49*7c568831SAndroid Build Coastguard Worker #endif
50*7c568831SAndroid Build Coastguard Worker 
51*7c568831SAndroid Build Coastguard Worker #ifndef SORT_CMP
52*7c568831SAndroid Build Coastguard Worker #define SORT_CMP(x, y)  ((x) < (y) ? -1 : ((x) == (y) ? 0 : 1))
53*7c568831SAndroid Build Coastguard Worker #endif
54*7c568831SAndroid Build Coastguard Worker 
55*7c568831SAndroid Build Coastguard Worker #ifndef TIM_SORT_STACK_SIZE
56*7c568831SAndroid Build Coastguard Worker #define TIM_SORT_STACK_SIZE 128
57*7c568831SAndroid Build Coastguard Worker #endif
58*7c568831SAndroid Build Coastguard Worker 
59*7c568831SAndroid Build Coastguard Worker #define SORT_SWAP(x,y) {SORT_TYPE __SORT_SWAP_t = (x); (x) = (y); (y) = __SORT_SWAP_t;}
60*7c568831SAndroid Build Coastguard Worker 
61*7c568831SAndroid Build Coastguard Worker 
62*7c568831SAndroid Build Coastguard Worker /* Common, type-agnostic functions and constants that we don't want to declare twice. */
63*7c568831SAndroid Build Coastguard Worker #ifndef SORT_COMMON_H
64*7c568831SAndroid Build Coastguard Worker #define SORT_COMMON_H
65*7c568831SAndroid Build Coastguard Worker 
66*7c568831SAndroid Build Coastguard Worker #ifndef MAX
67*7c568831SAndroid Build Coastguard Worker #define MAX(x,y) (((x) > (y) ? (x) : (y)))
68*7c568831SAndroid Build Coastguard Worker #endif
69*7c568831SAndroid Build Coastguard Worker 
70*7c568831SAndroid Build Coastguard Worker #ifndef MIN
71*7c568831SAndroid Build Coastguard Worker #define MIN(x,y) (((x) < (y) ? (x) : (y)))
72*7c568831SAndroid Build Coastguard Worker #endif
73*7c568831SAndroid Build Coastguard Worker 
74*7c568831SAndroid Build Coastguard Worker static int compute_minrun(const uint64_t);
75*7c568831SAndroid Build Coastguard Worker 
76*7c568831SAndroid Build Coastguard Worker #ifndef CLZ
77*7c568831SAndroid Build Coastguard Worker #if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ > 3))
78*7c568831SAndroid Build Coastguard Worker #define CLZ __builtin_clzll
79*7c568831SAndroid Build Coastguard Worker #else
80*7c568831SAndroid Build Coastguard Worker 
81*7c568831SAndroid Build Coastguard Worker static int clzll(uint64_t);
82*7c568831SAndroid Build Coastguard Worker 
83*7c568831SAndroid Build Coastguard Worker /* adapted from Hacker's Delight */
clzll(uint64_t x)84*7c568831SAndroid Build Coastguard Worker static int clzll(uint64_t x) {
85*7c568831SAndroid Build Coastguard Worker   int n;
86*7c568831SAndroid Build Coastguard Worker 
87*7c568831SAndroid Build Coastguard Worker   if (x == 0) {
88*7c568831SAndroid Build Coastguard Worker     return 64;
89*7c568831SAndroid Build Coastguard Worker   }
90*7c568831SAndroid Build Coastguard Worker 
91*7c568831SAndroid Build Coastguard Worker   n = 0;
92*7c568831SAndroid Build Coastguard Worker 
93*7c568831SAndroid Build Coastguard Worker   if (x <= 0x00000000FFFFFFFFL) {
94*7c568831SAndroid Build Coastguard Worker     n = n + 32;
95*7c568831SAndroid Build Coastguard Worker     x = x << 32;
96*7c568831SAndroid Build Coastguard Worker   }
97*7c568831SAndroid Build Coastguard Worker 
98*7c568831SAndroid Build Coastguard Worker   if (x <= 0x0000FFFFFFFFFFFFL) {
99*7c568831SAndroid Build Coastguard Worker     n = n + 16;
100*7c568831SAndroid Build Coastguard Worker     x = x << 16;
101*7c568831SAndroid Build Coastguard Worker   }
102*7c568831SAndroid Build Coastguard Worker 
103*7c568831SAndroid Build Coastguard Worker   if (x <= 0x00FFFFFFFFFFFFFFL) {
104*7c568831SAndroid Build Coastguard Worker     n = n + 8;
105*7c568831SAndroid Build Coastguard Worker     x = x << 8;
106*7c568831SAndroid Build Coastguard Worker   }
107*7c568831SAndroid Build Coastguard Worker 
108*7c568831SAndroid Build Coastguard Worker   if (x <= 0x0FFFFFFFFFFFFFFFL) {
109*7c568831SAndroid Build Coastguard Worker     n = n + 4;
110*7c568831SAndroid Build Coastguard Worker     x = x << 4;
111*7c568831SAndroid Build Coastguard Worker   }
112*7c568831SAndroid Build Coastguard Worker 
113*7c568831SAndroid Build Coastguard Worker   if (x <= 0x3FFFFFFFFFFFFFFFL) {
114*7c568831SAndroid Build Coastguard Worker     n = n + 2;
115*7c568831SAndroid Build Coastguard Worker     x = x << 2;
116*7c568831SAndroid Build Coastguard Worker   }
117*7c568831SAndroid Build Coastguard Worker 
118*7c568831SAndroid Build Coastguard Worker   if (x <= 0x7FFFFFFFFFFFFFFFL) {
119*7c568831SAndroid Build Coastguard Worker     n = n + 1;
120*7c568831SAndroid Build Coastguard Worker   }
121*7c568831SAndroid Build Coastguard Worker 
122*7c568831SAndroid Build Coastguard Worker   return n;
123*7c568831SAndroid Build Coastguard Worker }
124*7c568831SAndroid Build Coastguard Worker 
125*7c568831SAndroid Build Coastguard Worker #define CLZ clzll
126*7c568831SAndroid Build Coastguard Worker #endif
127*7c568831SAndroid Build Coastguard Worker #endif
128*7c568831SAndroid Build Coastguard Worker 
compute_minrun(const uint64_t size)129*7c568831SAndroid Build Coastguard Worker static __inline int compute_minrun(const uint64_t size) {
130*7c568831SAndroid Build Coastguard Worker   const int top_bit = 64 - CLZ(size);
131*7c568831SAndroid Build Coastguard Worker   const int shift = MAX(top_bit, 6) - 6;
132*7c568831SAndroid Build Coastguard Worker   const int minrun = size >> shift;
133*7c568831SAndroid Build Coastguard Worker   const uint64_t mask = (1ULL << shift) - 1;
134*7c568831SAndroid Build Coastguard Worker 
135*7c568831SAndroid Build Coastguard Worker   if (mask & size) {
136*7c568831SAndroid Build Coastguard Worker     return minrun + 1;
137*7c568831SAndroid Build Coastguard Worker   }
138*7c568831SAndroid Build Coastguard Worker 
139*7c568831SAndroid Build Coastguard Worker   return minrun;
140*7c568831SAndroid Build Coastguard Worker }
141*7c568831SAndroid Build Coastguard Worker 
142*7c568831SAndroid Build Coastguard Worker #endif /* SORT_COMMON_H */
143*7c568831SAndroid Build Coastguard Worker 
144*7c568831SAndroid Build Coastguard Worker #define SORT_CONCAT(x, y) x ## _ ## y
145*7c568831SAndroid Build Coastguard Worker #define SORT_MAKE_STR1(x, y) SORT_CONCAT(x,y)
146*7c568831SAndroid Build Coastguard Worker #define SORT_MAKE_STR(x) SORT_MAKE_STR1(SORT_NAME,x)
147*7c568831SAndroid Build Coastguard Worker 
148*7c568831SAndroid Build Coastguard Worker #define BINARY_INSERTION_FIND          SORT_MAKE_STR(binary_insertion_find)
149*7c568831SAndroid Build Coastguard Worker #define BINARY_INSERTION_SORT_START    SORT_MAKE_STR(binary_insertion_sort_start)
150*7c568831SAndroid Build Coastguard Worker #define BINARY_INSERTION_SORT          SORT_MAKE_STR(binary_insertion_sort)
151*7c568831SAndroid Build Coastguard Worker #define REVERSE_ELEMENTS               SORT_MAKE_STR(reverse_elements)
152*7c568831SAndroid Build Coastguard Worker #define COUNT_RUN                      SORT_MAKE_STR(count_run)
153*7c568831SAndroid Build Coastguard Worker #define CHECK_INVARIANT                SORT_MAKE_STR(check_invariant)
154*7c568831SAndroid Build Coastguard Worker #define TIM_SORT                       SORT_MAKE_STR(tim_sort)
155*7c568831SAndroid Build Coastguard Worker #define TIM_SORT_RESIZE                SORT_MAKE_STR(tim_sort_resize)
156*7c568831SAndroid Build Coastguard Worker #define TIM_SORT_MERGE                 SORT_MAKE_STR(tim_sort_merge)
157*7c568831SAndroid Build Coastguard Worker #define TIM_SORT_COLLAPSE              SORT_MAKE_STR(tim_sort_collapse)
158*7c568831SAndroid Build Coastguard Worker 
159*7c568831SAndroid Build Coastguard Worker #ifndef MAX
160*7c568831SAndroid Build Coastguard Worker #define MAX(x,y) (((x) > (y) ? (x) : (y)))
161*7c568831SAndroid Build Coastguard Worker #endif
162*7c568831SAndroid Build Coastguard Worker #ifndef MIN
163*7c568831SAndroid Build Coastguard Worker #define MIN(x,y) (((x) < (y) ? (x) : (y)))
164*7c568831SAndroid Build Coastguard Worker #endif
165*7c568831SAndroid Build Coastguard Worker 
166*7c568831SAndroid Build Coastguard Worker typedef struct {
167*7c568831SAndroid Build Coastguard Worker   size_t start;
168*7c568831SAndroid Build Coastguard Worker   size_t length;
169*7c568831SAndroid Build Coastguard Worker } TIM_SORT_RUN_T;
170*7c568831SAndroid Build Coastguard Worker 
171*7c568831SAndroid Build Coastguard Worker 
172*7c568831SAndroid Build Coastguard Worker XML_HIDDEN
173*7c568831SAndroid Build Coastguard Worker void BINARY_INSERTION_SORT(SORT_TYPE *dst, const size_t size);
174*7c568831SAndroid Build Coastguard Worker XML_HIDDEN
175*7c568831SAndroid Build Coastguard Worker void TIM_SORT(SORT_TYPE *dst, const size_t size);
176*7c568831SAndroid Build Coastguard Worker 
177*7c568831SAndroid Build Coastguard Worker 
178*7c568831SAndroid Build Coastguard Worker /* Function used to do a binary search for binary insertion sort */
BINARY_INSERTION_FIND(SORT_TYPE * dst,const SORT_TYPE x,const size_t size)179*7c568831SAndroid Build Coastguard Worker static __inline size_t BINARY_INSERTION_FIND(SORT_TYPE *dst, const SORT_TYPE x,
180*7c568831SAndroid Build Coastguard Worker     const size_t size) {
181*7c568831SAndroid Build Coastguard Worker   size_t l, c, r;
182*7c568831SAndroid Build Coastguard Worker   SORT_TYPE cx;
183*7c568831SAndroid Build Coastguard Worker   l = 0;
184*7c568831SAndroid Build Coastguard Worker   r = size - 1;
185*7c568831SAndroid Build Coastguard Worker   c = r >> 1;
186*7c568831SAndroid Build Coastguard Worker 
187*7c568831SAndroid Build Coastguard Worker   /* check for out of bounds at the beginning. */
188*7c568831SAndroid Build Coastguard Worker   if (SORT_CMP(x, dst[0]) < 0) {
189*7c568831SAndroid Build Coastguard Worker     return 0;
190*7c568831SAndroid Build Coastguard Worker   } else if (SORT_CMP(x, dst[r]) > 0) {
191*7c568831SAndroid Build Coastguard Worker     return r;
192*7c568831SAndroid Build Coastguard Worker   }
193*7c568831SAndroid Build Coastguard Worker 
194*7c568831SAndroid Build Coastguard Worker   cx = dst[c];
195*7c568831SAndroid Build Coastguard Worker 
196*7c568831SAndroid Build Coastguard Worker   while (1) {
197*7c568831SAndroid Build Coastguard Worker     const int val = SORT_CMP(x, cx);
198*7c568831SAndroid Build Coastguard Worker 
199*7c568831SAndroid Build Coastguard Worker     if (val < 0) {
200*7c568831SAndroid Build Coastguard Worker       if (c - l <= 1) {
201*7c568831SAndroid Build Coastguard Worker         return c;
202*7c568831SAndroid Build Coastguard Worker       }
203*7c568831SAndroid Build Coastguard Worker 
204*7c568831SAndroid Build Coastguard Worker       r = c;
205*7c568831SAndroid Build Coastguard Worker     } else { /* allow = for stability. The binary search favors the right. */
206*7c568831SAndroid Build Coastguard Worker       if (r - c <= 1) {
207*7c568831SAndroid Build Coastguard Worker         return c + 1;
208*7c568831SAndroid Build Coastguard Worker       }
209*7c568831SAndroid Build Coastguard Worker 
210*7c568831SAndroid Build Coastguard Worker       l = c;
211*7c568831SAndroid Build Coastguard Worker     }
212*7c568831SAndroid Build Coastguard Worker 
213*7c568831SAndroid Build Coastguard Worker     c = l + ((r - l) >> 1);
214*7c568831SAndroid Build Coastguard Worker     cx = dst[c];
215*7c568831SAndroid Build Coastguard Worker   }
216*7c568831SAndroid Build Coastguard Worker }
217*7c568831SAndroid Build Coastguard Worker 
218*7c568831SAndroid Build Coastguard Worker /* Binary insertion sort, but knowing that the first "start" entries are sorted.  Used in timsort. */
BINARY_INSERTION_SORT_START(SORT_TYPE * dst,const size_t start,const size_t size)219*7c568831SAndroid Build Coastguard Worker static void BINARY_INSERTION_SORT_START(SORT_TYPE *dst, const size_t start, const size_t size) {
220*7c568831SAndroid Build Coastguard Worker   size_t i;
221*7c568831SAndroid Build Coastguard Worker 
222*7c568831SAndroid Build Coastguard Worker   for (i = start; i < size; i++) {
223*7c568831SAndroid Build Coastguard Worker     size_t j;
224*7c568831SAndroid Build Coastguard Worker     SORT_TYPE x;
225*7c568831SAndroid Build Coastguard Worker     size_t location;
226*7c568831SAndroid Build Coastguard Worker 
227*7c568831SAndroid Build Coastguard Worker     /* If this entry is already correct, just move along */
228*7c568831SAndroid Build Coastguard Worker     if (SORT_CMP(dst[i - 1], dst[i]) <= 0) {
229*7c568831SAndroid Build Coastguard Worker       continue;
230*7c568831SAndroid Build Coastguard Worker     }
231*7c568831SAndroid Build Coastguard Worker 
232*7c568831SAndroid Build Coastguard Worker     /* Else we need to find the right place, shift everything over, and squeeze in */
233*7c568831SAndroid Build Coastguard Worker     x = dst[i];
234*7c568831SAndroid Build Coastguard Worker     location = BINARY_INSERTION_FIND(dst, x, i);
235*7c568831SAndroid Build Coastguard Worker 
236*7c568831SAndroid Build Coastguard Worker     for (j = i - 1; j >= location; j--) {
237*7c568831SAndroid Build Coastguard Worker       dst[j + 1] = dst[j];
238*7c568831SAndroid Build Coastguard Worker 
239*7c568831SAndroid Build Coastguard Worker       if (j == 0) { /* check edge case because j is unsigned */
240*7c568831SAndroid Build Coastguard Worker         break;
241*7c568831SAndroid Build Coastguard Worker       }
242*7c568831SAndroid Build Coastguard Worker     }
243*7c568831SAndroid Build Coastguard Worker 
244*7c568831SAndroid Build Coastguard Worker     dst[location] = x;
245*7c568831SAndroid Build Coastguard Worker   }
246*7c568831SAndroid Build Coastguard Worker }
247*7c568831SAndroid Build Coastguard Worker 
248*7c568831SAndroid Build Coastguard Worker /* Binary insertion sort */
BINARY_INSERTION_SORT(SORT_TYPE * dst,const size_t size)249*7c568831SAndroid Build Coastguard Worker void BINARY_INSERTION_SORT(SORT_TYPE *dst, const size_t size) {
250*7c568831SAndroid Build Coastguard Worker   /* don't bother sorting an array of size <= 1 */
251*7c568831SAndroid Build Coastguard Worker   if (size <= 1) {
252*7c568831SAndroid Build Coastguard Worker     return;
253*7c568831SAndroid Build Coastguard Worker   }
254*7c568831SAndroid Build Coastguard Worker 
255*7c568831SAndroid Build Coastguard Worker   BINARY_INSERTION_SORT_START(dst, 1, size);
256*7c568831SAndroid Build Coastguard Worker }
257*7c568831SAndroid Build Coastguard Worker 
258*7c568831SAndroid Build Coastguard Worker /* timsort implementation, based on timsort.txt */
259*7c568831SAndroid Build Coastguard Worker 
REVERSE_ELEMENTS(SORT_TYPE * dst,size_t start,size_t end)260*7c568831SAndroid Build Coastguard Worker static __inline void REVERSE_ELEMENTS(SORT_TYPE *dst, size_t start, size_t end) {
261*7c568831SAndroid Build Coastguard Worker   while (1) {
262*7c568831SAndroid Build Coastguard Worker     if (start >= end) {
263*7c568831SAndroid Build Coastguard Worker       return;
264*7c568831SAndroid Build Coastguard Worker     }
265*7c568831SAndroid Build Coastguard Worker 
266*7c568831SAndroid Build Coastguard Worker     SORT_SWAP(dst[start], dst[end]);
267*7c568831SAndroid Build Coastguard Worker     start++;
268*7c568831SAndroid Build Coastguard Worker     end--;
269*7c568831SAndroid Build Coastguard Worker   }
270*7c568831SAndroid Build Coastguard Worker }
271*7c568831SAndroid Build Coastguard Worker 
COUNT_RUN(SORT_TYPE * dst,const size_t start,const size_t size)272*7c568831SAndroid Build Coastguard Worker static size_t COUNT_RUN(SORT_TYPE *dst, const size_t start, const size_t size) {
273*7c568831SAndroid Build Coastguard Worker   size_t curr;
274*7c568831SAndroid Build Coastguard Worker 
275*7c568831SAndroid Build Coastguard Worker   if (size - start == 1) {
276*7c568831SAndroid Build Coastguard Worker     return 1;
277*7c568831SAndroid Build Coastguard Worker   }
278*7c568831SAndroid Build Coastguard Worker 
279*7c568831SAndroid Build Coastguard Worker   if (start >= size - 2) {
280*7c568831SAndroid Build Coastguard Worker     if (SORT_CMP(dst[size - 2], dst[size - 1]) > 0) {
281*7c568831SAndroid Build Coastguard Worker       SORT_SWAP(dst[size - 2], dst[size - 1]);
282*7c568831SAndroid Build Coastguard Worker     }
283*7c568831SAndroid Build Coastguard Worker 
284*7c568831SAndroid Build Coastguard Worker     return 2;
285*7c568831SAndroid Build Coastguard Worker   }
286*7c568831SAndroid Build Coastguard Worker 
287*7c568831SAndroid Build Coastguard Worker   curr = start + 2;
288*7c568831SAndroid Build Coastguard Worker 
289*7c568831SAndroid Build Coastguard Worker   if (SORT_CMP(dst[start], dst[start + 1]) <= 0) {
290*7c568831SAndroid Build Coastguard Worker     /* increasing run */
291*7c568831SAndroid Build Coastguard Worker     while (1) {
292*7c568831SAndroid Build Coastguard Worker       if (curr == size - 1) {
293*7c568831SAndroid Build Coastguard Worker         break;
294*7c568831SAndroid Build Coastguard Worker       }
295*7c568831SAndroid Build Coastguard Worker 
296*7c568831SAndroid Build Coastguard Worker       if (SORT_CMP(dst[curr - 1], dst[curr]) > 0) {
297*7c568831SAndroid Build Coastguard Worker         break;
298*7c568831SAndroid Build Coastguard Worker       }
299*7c568831SAndroid Build Coastguard Worker 
300*7c568831SAndroid Build Coastguard Worker       curr++;
301*7c568831SAndroid Build Coastguard Worker     }
302*7c568831SAndroid Build Coastguard Worker 
303*7c568831SAndroid Build Coastguard Worker     return curr - start;
304*7c568831SAndroid Build Coastguard Worker   } else {
305*7c568831SAndroid Build Coastguard Worker     /* decreasing run */
306*7c568831SAndroid Build Coastguard Worker     while (1) {
307*7c568831SAndroid Build Coastguard Worker       if (curr == size - 1) {
308*7c568831SAndroid Build Coastguard Worker         break;
309*7c568831SAndroid Build Coastguard Worker       }
310*7c568831SAndroid Build Coastguard Worker 
311*7c568831SAndroid Build Coastguard Worker       if (SORT_CMP(dst[curr - 1], dst[curr]) <= 0) {
312*7c568831SAndroid Build Coastguard Worker         break;
313*7c568831SAndroid Build Coastguard Worker       }
314*7c568831SAndroid Build Coastguard Worker 
315*7c568831SAndroid Build Coastguard Worker       curr++;
316*7c568831SAndroid Build Coastguard Worker     }
317*7c568831SAndroid Build Coastguard Worker 
318*7c568831SAndroid Build Coastguard Worker     /* reverse in-place */
319*7c568831SAndroid Build Coastguard Worker     REVERSE_ELEMENTS(dst, start, curr - 1);
320*7c568831SAndroid Build Coastguard Worker     return curr - start;
321*7c568831SAndroid Build Coastguard Worker   }
322*7c568831SAndroid Build Coastguard Worker }
323*7c568831SAndroid Build Coastguard Worker 
CHECK_INVARIANT(TIM_SORT_RUN_T * stack,const int stack_curr)324*7c568831SAndroid Build Coastguard Worker static int CHECK_INVARIANT(TIM_SORT_RUN_T *stack, const int stack_curr) {
325*7c568831SAndroid Build Coastguard Worker   size_t A, B, C;
326*7c568831SAndroid Build Coastguard Worker 
327*7c568831SAndroid Build Coastguard Worker   if (stack_curr < 2) {
328*7c568831SAndroid Build Coastguard Worker     return 1;
329*7c568831SAndroid Build Coastguard Worker   }
330*7c568831SAndroid Build Coastguard Worker 
331*7c568831SAndroid Build Coastguard Worker   if (stack_curr == 2) {
332*7c568831SAndroid Build Coastguard Worker     const size_t A1 = stack[stack_curr - 2].length;
333*7c568831SAndroid Build Coastguard Worker     const size_t B1 = stack[stack_curr - 1].length;
334*7c568831SAndroid Build Coastguard Worker 
335*7c568831SAndroid Build Coastguard Worker     if (A1 <= B1) {
336*7c568831SAndroid Build Coastguard Worker       return 0;
337*7c568831SAndroid Build Coastguard Worker     }
338*7c568831SAndroid Build Coastguard Worker 
339*7c568831SAndroid Build Coastguard Worker     return 1;
340*7c568831SAndroid Build Coastguard Worker   }
341*7c568831SAndroid Build Coastguard Worker 
342*7c568831SAndroid Build Coastguard Worker   A = stack[stack_curr - 3].length;
343*7c568831SAndroid Build Coastguard Worker   B = stack[stack_curr - 2].length;
344*7c568831SAndroid Build Coastguard Worker   C = stack[stack_curr - 1].length;
345*7c568831SAndroid Build Coastguard Worker 
346*7c568831SAndroid Build Coastguard Worker   if ((A <= B + C) || (B <= C)) {
347*7c568831SAndroid Build Coastguard Worker     return 0;
348*7c568831SAndroid Build Coastguard Worker   }
349*7c568831SAndroid Build Coastguard Worker 
350*7c568831SAndroid Build Coastguard Worker   return 1;
351*7c568831SAndroid Build Coastguard Worker }
352*7c568831SAndroid Build Coastguard Worker 
353*7c568831SAndroid Build Coastguard Worker typedef struct {
354*7c568831SAndroid Build Coastguard Worker   size_t alloc;
355*7c568831SAndroid Build Coastguard Worker   SORT_TYPE *storage;
356*7c568831SAndroid Build Coastguard Worker } TEMP_STORAGE_T;
357*7c568831SAndroid Build Coastguard Worker 
TIM_SORT_RESIZE(TEMP_STORAGE_T * store,const size_t new_size)358*7c568831SAndroid Build Coastguard Worker static void TIM_SORT_RESIZE(TEMP_STORAGE_T *store, const size_t new_size) {
359*7c568831SAndroid Build Coastguard Worker   if (store->alloc < new_size) {
360*7c568831SAndroid Build Coastguard Worker     SORT_TYPE *tempstore = (SORT_TYPE *)realloc(store->storage, new_size * sizeof(SORT_TYPE));
361*7c568831SAndroid Build Coastguard Worker 
362*7c568831SAndroid Build Coastguard Worker     if (tempstore == NULL) {
363*7c568831SAndroid Build Coastguard Worker       fprintf(stderr, "Error allocating temporary storage for tim sort: need %lu bytes",
364*7c568831SAndroid Build Coastguard Worker               (unsigned long)(sizeof(SORT_TYPE) * new_size));
365*7c568831SAndroid Build Coastguard Worker       exit(1);
366*7c568831SAndroid Build Coastguard Worker     }
367*7c568831SAndroid Build Coastguard Worker 
368*7c568831SAndroid Build Coastguard Worker     store->storage = tempstore;
369*7c568831SAndroid Build Coastguard Worker     store->alloc = new_size;
370*7c568831SAndroid Build Coastguard Worker   }
371*7c568831SAndroid Build Coastguard Worker }
372*7c568831SAndroid Build Coastguard Worker 
TIM_SORT_MERGE(SORT_TYPE * dst,const TIM_SORT_RUN_T * stack,const int stack_curr,TEMP_STORAGE_T * store)373*7c568831SAndroid Build Coastguard Worker static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const int stack_curr,
374*7c568831SAndroid Build Coastguard Worker                            TEMP_STORAGE_T *store) {
375*7c568831SAndroid Build Coastguard Worker   const size_t A = stack[stack_curr - 2].length;
376*7c568831SAndroid Build Coastguard Worker   const size_t B = stack[stack_curr - 1].length;
377*7c568831SAndroid Build Coastguard Worker   const size_t curr = stack[stack_curr - 2].start;
378*7c568831SAndroid Build Coastguard Worker   SORT_TYPE *storage;
379*7c568831SAndroid Build Coastguard Worker   size_t i, j, k;
380*7c568831SAndroid Build Coastguard Worker   TIM_SORT_RESIZE(store, MIN(A, B));
381*7c568831SAndroid Build Coastguard Worker   storage = store->storage;
382*7c568831SAndroid Build Coastguard Worker 
383*7c568831SAndroid Build Coastguard Worker   /* left merge */
384*7c568831SAndroid Build Coastguard Worker   if (A < B) {
385*7c568831SAndroid Build Coastguard Worker     memcpy(storage, &dst[curr], A * sizeof(SORT_TYPE));
386*7c568831SAndroid Build Coastguard Worker     i = 0;
387*7c568831SAndroid Build Coastguard Worker     j = curr + A;
388*7c568831SAndroid Build Coastguard Worker 
389*7c568831SAndroid Build Coastguard Worker     for (k = curr; k < curr + A + B; k++) {
390*7c568831SAndroid Build Coastguard Worker       if ((i < A) && (j < curr + A + B)) {
391*7c568831SAndroid Build Coastguard Worker         if (SORT_CMP(storage[i], dst[j]) <= 0) {
392*7c568831SAndroid Build Coastguard Worker           dst[k] = storage[i++];
393*7c568831SAndroid Build Coastguard Worker         } else {
394*7c568831SAndroid Build Coastguard Worker           dst[k] = dst[j++];
395*7c568831SAndroid Build Coastguard Worker         }
396*7c568831SAndroid Build Coastguard Worker       } else if (i < A) {
397*7c568831SAndroid Build Coastguard Worker         dst[k] = storage[i++];
398*7c568831SAndroid Build Coastguard Worker       } else {
399*7c568831SAndroid Build Coastguard Worker         break;
400*7c568831SAndroid Build Coastguard Worker       }
401*7c568831SAndroid Build Coastguard Worker     }
402*7c568831SAndroid Build Coastguard Worker   } else {
403*7c568831SAndroid Build Coastguard Worker     /* right merge */
404*7c568831SAndroid Build Coastguard Worker     memcpy(storage, &dst[curr + A], B * sizeof(SORT_TYPE));
405*7c568831SAndroid Build Coastguard Worker     i = B;
406*7c568831SAndroid Build Coastguard Worker     j = curr + A;
407*7c568831SAndroid Build Coastguard Worker     k = curr + A + B;
408*7c568831SAndroid Build Coastguard Worker 
409*7c568831SAndroid Build Coastguard Worker     while (k > curr) {
410*7c568831SAndroid Build Coastguard Worker       k--;
411*7c568831SAndroid Build Coastguard Worker       if ((i > 0) && (j > curr)) {
412*7c568831SAndroid Build Coastguard Worker         if (SORT_CMP(dst[j - 1], storage[i - 1]) > 0) {
413*7c568831SAndroid Build Coastguard Worker           dst[k] = dst[--j];
414*7c568831SAndroid Build Coastguard Worker         } else {
415*7c568831SAndroid Build Coastguard Worker           dst[k] = storage[--i];
416*7c568831SAndroid Build Coastguard Worker         }
417*7c568831SAndroid Build Coastguard Worker       } else if (i > 0) {
418*7c568831SAndroid Build Coastguard Worker         dst[k] = storage[--i];
419*7c568831SAndroid Build Coastguard Worker       } else {
420*7c568831SAndroid Build Coastguard Worker         break;
421*7c568831SAndroid Build Coastguard Worker       }
422*7c568831SAndroid Build Coastguard Worker     }
423*7c568831SAndroid Build Coastguard Worker   }
424*7c568831SAndroid Build Coastguard Worker }
425*7c568831SAndroid Build Coastguard Worker 
TIM_SORT_COLLAPSE(SORT_TYPE * dst,TIM_SORT_RUN_T * stack,int stack_curr,TEMP_STORAGE_T * store,const size_t size)426*7c568831SAndroid Build Coastguard Worker static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_curr,
427*7c568831SAndroid Build Coastguard Worker                              TEMP_STORAGE_T *store, const size_t size) {
428*7c568831SAndroid Build Coastguard Worker   while (1) {
429*7c568831SAndroid Build Coastguard Worker     size_t A, B, C, D;
430*7c568831SAndroid Build Coastguard Worker     int ABC, BCD, CD;
431*7c568831SAndroid Build Coastguard Worker 
432*7c568831SAndroid Build Coastguard Worker     /* if the stack only has one thing on it, we are done with the collapse */
433*7c568831SAndroid Build Coastguard Worker     if (stack_curr <= 1) {
434*7c568831SAndroid Build Coastguard Worker       break;
435*7c568831SAndroid Build Coastguard Worker     }
436*7c568831SAndroid Build Coastguard Worker 
437*7c568831SAndroid Build Coastguard Worker     /* if this is the last merge, just do it */
438*7c568831SAndroid Build Coastguard Worker     if ((stack_curr == 2) && (stack[0].length + stack[1].length == size)) {
439*7c568831SAndroid Build Coastguard Worker       TIM_SORT_MERGE(dst, stack, stack_curr, store);
440*7c568831SAndroid Build Coastguard Worker       stack[0].length += stack[1].length;
441*7c568831SAndroid Build Coastguard Worker       stack_curr--;
442*7c568831SAndroid Build Coastguard Worker       break;
443*7c568831SAndroid Build Coastguard Worker     }
444*7c568831SAndroid Build Coastguard Worker     /* check if the invariant is off for a stack of 2 elements */
445*7c568831SAndroid Build Coastguard Worker     else if ((stack_curr == 2) && (stack[0].length <= stack[1].length)) {
446*7c568831SAndroid Build Coastguard Worker       TIM_SORT_MERGE(dst, stack, stack_curr, store);
447*7c568831SAndroid Build Coastguard Worker       stack[0].length += stack[1].length;
448*7c568831SAndroid Build Coastguard Worker       stack_curr--;
449*7c568831SAndroid Build Coastguard Worker       break;
450*7c568831SAndroid Build Coastguard Worker     } else if (stack_curr == 2) {
451*7c568831SAndroid Build Coastguard Worker       break;
452*7c568831SAndroid Build Coastguard Worker     }
453*7c568831SAndroid Build Coastguard Worker 
454*7c568831SAndroid Build Coastguard Worker     B = stack[stack_curr - 3].length;
455*7c568831SAndroid Build Coastguard Worker     C = stack[stack_curr - 2].length;
456*7c568831SAndroid Build Coastguard Worker     D = stack[stack_curr - 1].length;
457*7c568831SAndroid Build Coastguard Worker 
458*7c568831SAndroid Build Coastguard Worker     if (stack_curr >= 4) {
459*7c568831SAndroid Build Coastguard Worker       A = stack[stack_curr - 4].length;
460*7c568831SAndroid Build Coastguard Worker       ABC = (A <= B + C);
461*7c568831SAndroid Build Coastguard Worker     } else {
462*7c568831SAndroid Build Coastguard Worker       ABC = 0;
463*7c568831SAndroid Build Coastguard Worker     }
464*7c568831SAndroid Build Coastguard Worker 
465*7c568831SAndroid Build Coastguard Worker     BCD = (B <= C + D) || ABC;
466*7c568831SAndroid Build Coastguard Worker     CD = (C <= D);
467*7c568831SAndroid Build Coastguard Worker 
468*7c568831SAndroid Build Coastguard Worker     /* Both invariants are good */
469*7c568831SAndroid Build Coastguard Worker     if (!BCD && !CD) {
470*7c568831SAndroid Build Coastguard Worker       break;
471*7c568831SAndroid Build Coastguard Worker     }
472*7c568831SAndroid Build Coastguard Worker 
473*7c568831SAndroid Build Coastguard Worker     /* left merge */
474*7c568831SAndroid Build Coastguard Worker     if (BCD && !CD) {
475*7c568831SAndroid Build Coastguard Worker       TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
476*7c568831SAndroid Build Coastguard Worker       stack[stack_curr - 3].length += stack[stack_curr - 2].length;
477*7c568831SAndroid Build Coastguard Worker       stack[stack_curr - 2] = stack[stack_curr - 1];
478*7c568831SAndroid Build Coastguard Worker       stack_curr--;
479*7c568831SAndroid Build Coastguard Worker     } else {
480*7c568831SAndroid Build Coastguard Worker       /* right merge */
481*7c568831SAndroid Build Coastguard Worker       TIM_SORT_MERGE(dst, stack, stack_curr, store);
482*7c568831SAndroid Build Coastguard Worker       stack[stack_curr - 2].length += stack[stack_curr - 1].length;
483*7c568831SAndroid Build Coastguard Worker       stack_curr--;
484*7c568831SAndroid Build Coastguard Worker     }
485*7c568831SAndroid Build Coastguard Worker   }
486*7c568831SAndroid Build Coastguard Worker 
487*7c568831SAndroid Build Coastguard Worker   return stack_curr;
488*7c568831SAndroid Build Coastguard Worker }
489*7c568831SAndroid Build Coastguard Worker 
PUSH_NEXT(SORT_TYPE * dst,const size_t size,TEMP_STORAGE_T * store,const size_t minrun,TIM_SORT_RUN_T * run_stack,size_t * stack_curr,size_t * curr)490*7c568831SAndroid Build Coastguard Worker static __inline int PUSH_NEXT(SORT_TYPE *dst,
491*7c568831SAndroid Build Coastguard Worker                               const size_t size,
492*7c568831SAndroid Build Coastguard Worker                               TEMP_STORAGE_T *store,
493*7c568831SAndroid Build Coastguard Worker                               const size_t minrun,
494*7c568831SAndroid Build Coastguard Worker                               TIM_SORT_RUN_T *run_stack,
495*7c568831SAndroid Build Coastguard Worker                               size_t *stack_curr,
496*7c568831SAndroid Build Coastguard Worker                               size_t *curr) {
497*7c568831SAndroid Build Coastguard Worker   size_t len = COUNT_RUN(dst, *curr, size);
498*7c568831SAndroid Build Coastguard Worker   size_t run = minrun;
499*7c568831SAndroid Build Coastguard Worker 
500*7c568831SAndroid Build Coastguard Worker   if (run > size - *curr) {
501*7c568831SAndroid Build Coastguard Worker     run = size - *curr;
502*7c568831SAndroid Build Coastguard Worker   }
503*7c568831SAndroid Build Coastguard Worker 
504*7c568831SAndroid Build Coastguard Worker   if (run > len) {
505*7c568831SAndroid Build Coastguard Worker     BINARY_INSERTION_SORT_START(&dst[*curr], len, run);
506*7c568831SAndroid Build Coastguard Worker     len = run;
507*7c568831SAndroid Build Coastguard Worker   }
508*7c568831SAndroid Build Coastguard Worker 
509*7c568831SAndroid Build Coastguard Worker   run_stack[*stack_curr].start = *curr;
510*7c568831SAndroid Build Coastguard Worker   run_stack[*stack_curr].length = len;
511*7c568831SAndroid Build Coastguard Worker   (*stack_curr)++;
512*7c568831SAndroid Build Coastguard Worker   *curr += len;
513*7c568831SAndroid Build Coastguard Worker 
514*7c568831SAndroid Build Coastguard Worker   if (*curr == size) {
515*7c568831SAndroid Build Coastguard Worker     /* finish up */
516*7c568831SAndroid Build Coastguard Worker     while (*stack_curr > 1) {
517*7c568831SAndroid Build Coastguard Worker       TIM_SORT_MERGE(dst, run_stack, *stack_curr, store);
518*7c568831SAndroid Build Coastguard Worker       run_stack[*stack_curr - 2].length += run_stack[*stack_curr - 1].length;
519*7c568831SAndroid Build Coastguard Worker       (*stack_curr)--;
520*7c568831SAndroid Build Coastguard Worker     }
521*7c568831SAndroid Build Coastguard Worker 
522*7c568831SAndroid Build Coastguard Worker     if (store->storage != NULL) {
523*7c568831SAndroid Build Coastguard Worker       free(store->storage);
524*7c568831SAndroid Build Coastguard Worker       store->storage = NULL;
525*7c568831SAndroid Build Coastguard Worker     }
526*7c568831SAndroid Build Coastguard Worker 
527*7c568831SAndroid Build Coastguard Worker     return 0;
528*7c568831SAndroid Build Coastguard Worker   }
529*7c568831SAndroid Build Coastguard Worker 
530*7c568831SAndroid Build Coastguard Worker   return 1;
531*7c568831SAndroid Build Coastguard Worker }
532*7c568831SAndroid Build Coastguard Worker 
TIM_SORT(SORT_TYPE * dst,const size_t size)533*7c568831SAndroid Build Coastguard Worker void TIM_SORT(SORT_TYPE *dst, const size_t size) {
534*7c568831SAndroid Build Coastguard Worker   size_t minrun;
535*7c568831SAndroid Build Coastguard Worker   TEMP_STORAGE_T _store, *store;
536*7c568831SAndroid Build Coastguard Worker   TIM_SORT_RUN_T run_stack[TIM_SORT_STACK_SIZE];
537*7c568831SAndroid Build Coastguard Worker   size_t stack_curr = 0;
538*7c568831SAndroid Build Coastguard Worker   size_t curr = 0;
539*7c568831SAndroid Build Coastguard Worker 
540*7c568831SAndroid Build Coastguard Worker   /* don't bother sorting an array of size 1 */
541*7c568831SAndroid Build Coastguard Worker   if (size <= 1) {
542*7c568831SAndroid Build Coastguard Worker     return;
543*7c568831SAndroid Build Coastguard Worker   }
544*7c568831SAndroid Build Coastguard Worker 
545*7c568831SAndroid Build Coastguard Worker   if (size < 64) {
546*7c568831SAndroid Build Coastguard Worker     BINARY_INSERTION_SORT(dst, size);
547*7c568831SAndroid Build Coastguard Worker     return;
548*7c568831SAndroid Build Coastguard Worker   }
549*7c568831SAndroid Build Coastguard Worker 
550*7c568831SAndroid Build Coastguard Worker   /* compute the minimum run length */
551*7c568831SAndroid Build Coastguard Worker   minrun = compute_minrun(size);
552*7c568831SAndroid Build Coastguard Worker   /* temporary storage for merges */
553*7c568831SAndroid Build Coastguard Worker   store = &_store;
554*7c568831SAndroid Build Coastguard Worker   store->alloc = 0;
555*7c568831SAndroid Build Coastguard Worker   store->storage = NULL;
556*7c568831SAndroid Build Coastguard Worker 
557*7c568831SAndroid Build Coastguard Worker   if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
558*7c568831SAndroid Build Coastguard Worker     return;
559*7c568831SAndroid Build Coastguard Worker   }
560*7c568831SAndroid Build Coastguard Worker 
561*7c568831SAndroid Build Coastguard Worker   if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
562*7c568831SAndroid Build Coastguard Worker     return;
563*7c568831SAndroid Build Coastguard Worker   }
564*7c568831SAndroid Build Coastguard Worker 
565*7c568831SAndroid Build Coastguard Worker   if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
566*7c568831SAndroid Build Coastguard Worker     return;
567*7c568831SAndroid Build Coastguard Worker   }
568*7c568831SAndroid Build Coastguard Worker 
569*7c568831SAndroid Build Coastguard Worker   while (1) {
570*7c568831SAndroid Build Coastguard Worker     if (!CHECK_INVARIANT(run_stack, stack_curr)) {
571*7c568831SAndroid Build Coastguard Worker       stack_curr = TIM_SORT_COLLAPSE(dst, run_stack, stack_curr, store, size);
572*7c568831SAndroid Build Coastguard Worker       continue;
573*7c568831SAndroid Build Coastguard Worker     }
574*7c568831SAndroid Build Coastguard Worker 
575*7c568831SAndroid Build Coastguard Worker     if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
576*7c568831SAndroid Build Coastguard Worker       return;
577*7c568831SAndroid Build Coastguard Worker     }
578*7c568831SAndroid Build Coastguard Worker   }
579*7c568831SAndroid Build Coastguard Worker }
580*7c568831SAndroid Build Coastguard Worker 
581*7c568831SAndroid Build Coastguard Worker #undef SORT_CONCAT
582*7c568831SAndroid Build Coastguard Worker #undef SORT_MAKE_STR1
583*7c568831SAndroid Build Coastguard Worker #undef SORT_MAKE_STR
584*7c568831SAndroid Build Coastguard Worker #undef SORT_NAME
585*7c568831SAndroid Build Coastguard Worker #undef SORT_TYPE
586*7c568831SAndroid Build Coastguard Worker #undef SORT_CMP
587*7c568831SAndroid Build Coastguard Worker #undef TEMP_STORAGE_T
588*7c568831SAndroid Build Coastguard Worker #undef TIM_SORT_RUN_T
589*7c568831SAndroid Build Coastguard Worker #undef PUSH_NEXT
590*7c568831SAndroid Build Coastguard Worker #undef SORT_SWAP
591*7c568831SAndroid Build Coastguard Worker #undef SORT_CONCAT
592*7c568831SAndroid Build Coastguard Worker #undef SORT_MAKE_STR1
593*7c568831SAndroid Build Coastguard Worker #undef SORT_MAKE_STR
594*7c568831SAndroid Build Coastguard Worker #undef BINARY_INSERTION_FIND
595*7c568831SAndroid Build Coastguard Worker #undef BINARY_INSERTION_SORT_START
596*7c568831SAndroid Build Coastguard Worker #undef BINARY_INSERTION_SORT
597*7c568831SAndroid Build Coastguard Worker #undef REVERSE_ELEMENTS
598*7c568831SAndroid Build Coastguard Worker #undef COUNT_RUN
599*7c568831SAndroid Build Coastguard Worker #undef TIM_SORT
600*7c568831SAndroid Build Coastguard Worker #undef TIM_SORT_RESIZE
601*7c568831SAndroid Build Coastguard Worker #undef TIM_SORT_COLLAPSE
602*7c568831SAndroid Build Coastguard Worker #undef TIM_SORT_RUN_T
603*7c568831SAndroid Build Coastguard Worker #undef TEMP_STORAGE_T
604