Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "gdk.h"
15 : #include "gdk_private.h"
16 :
17 : struct qsort_t {
18 : unsigned int hs;
19 : unsigned int ts;
20 : int (*cmp)(const void *, const void *);
21 : const char *base;
22 : const void *nil;
23 : };
24 :
25 : #define glue(a, b, c) a ## b ## c
26 : #define CONCAT2(a, b) a ## b
27 : #define CONCAT3(a, b, c) glue(a, b, c)
28 :
29 : /* nil is smallest value, i.e. first for ascending, last for descending */
30 : #define fixltf(i, j, TPE) (((TPE *) h)[i] < ((TPE *) h)[j])
31 : #define fixlef(i, j, TPE) (((TPE *) h)[i] <= ((TPE *) h)[j])
32 : #define fixgtl(i, j, TPE) (((TPE *) h)[i] > ((TPE *) h)[j])
33 : #define fixgel(i, j, TPE) (((TPE *) h)[i] >= ((TPE *) h)[j])
34 :
35 : /* nil is largest value, i.e. last for ascending, first for descending */
36 : #define fixltl(i, j, TPE) (!fixnil(i, TPE) && (fixnil(j, TPE) || ((TPE *) h)[i] < ((TPE *) h)[j]))
37 : #define fixlel(i, j, TPE) (fixnil(j, TPE) || (!fixnil(i, TPE) && ((TPE *) h)[i] <= ((TPE *) h)[j]))
38 : #define fixgtf(i, j, TPE) (!fixnil(j, TPE) && (fixnil(i, TPE) || ((TPE *) h)[i] > ((TPE *) h)[j]))
39 : #define fixgef(i, j, TPE) (fixnil(i, TPE) || (!fixnil(j, TPE) && ((TPE *) h)[i] >= ((TPE *) h)[j]))
40 :
41 : #define fixeq(i, j, TPE) (((TPE *) h)[i] == ((TPE *) h)[j])
42 : #define fixnil(i, TPE) is_##TPE##_nil(((TPE *) h)[i])
43 : #define fixswap(i, j, TPE) \
44 : do { \
45 : TPE _t = ((TPE *) h)[i]; \
46 : ((TPE *) h)[i] = ((TPE *) h)[j]; \
47 : ((TPE *) h)[j] = _t; \
48 : if (t) \
49 : SWAP1((i) * buf->ts, (j) * buf->ts, t, buf->ts); \
50 : } while (0)
51 :
52 : #define bteltf(i, j) fixltf(i, j, bte)
53 : #define btelef(i, j) fixlef(i, j, bte)
54 : #define bteltl(i, j) fixltl(i, j, bte)
55 : #define btelel(i, j) fixlel(i, j, bte)
56 : #define bteltl_rev(i, j) fixgtl(i, j, bte)
57 : #define btelel_rev(i, j) fixgel(i, j, bte)
58 : #define bteltf_rev(i, j) fixgtf(i, j, bte)
59 : #define btelef_rev(i, j) fixgef(i, j, bte)
60 : #define bteeq(i, j) fixeq(i, j, bte)
61 : #define btenil(i) fixnil(i, bte)
62 : #define bteswap(i, j) fixswap(i, j, bte)
63 :
64 : #define shtltf(i, j) fixltf(i, j, sht)
65 : #define shtlef(i, j) fixlef(i, j, sht)
66 : #define shtltl(i, j) fixltl(i, j, sht)
67 : #define shtlel(i, j) fixlel(i, j, sht)
68 : #define shtltl_rev(i, j) fixgtl(i, j, sht)
69 : #define shtlel_rev(i, j) fixgel(i, j, sht)
70 : #define shtltf_rev(i, j) fixgtf(i, j, sht)
71 : #define shtlef_rev(i, j) fixgef(i, j, sht)
72 : #define shteq(i, j) fixeq(i, j, sht)
73 : #define shtnil(i) fixnil(i, sht)
74 : #define shtswap(i, j) fixswap(i, j, sht)
75 :
76 : #define intltf(i, j) fixltf(i, j, int)
77 : #define intlef(i, j) fixlef(i, j, int)
78 : #define intltl(i, j) fixltl(i, j, int)
79 : #define intlel(i, j) fixlel(i, j, int)
80 : #define intltl_rev(i, j) fixgtl(i, j, int)
81 : #define intlel_rev(i, j) fixgel(i, j, int)
82 : #define intltf_rev(i, j) fixgtf(i, j, int)
83 : #define intlef_rev(i, j) fixgef(i, j, int)
84 : #define inteq(i, j) fixeq(i, j, int)
85 : #define intnil(i) fixnil(i, int)
86 : #define intswap(i, j) fixswap(i, j, int)
87 :
88 : #define lngltf(i, j) fixltf(i, j, lng)
89 : #define lnglef(i, j) fixlef(i, j, lng)
90 : #define lngltl(i, j) fixltl(i, j, lng)
91 : #define lnglel(i, j) fixlel(i, j, lng)
92 : #define lngltl_rev(i, j) fixgtl(i, j, lng)
93 : #define lnglel_rev(i, j) fixgel(i, j, lng)
94 : #define lngltf_rev(i, j) fixgtf(i, j, lng)
95 : #define lnglef_rev(i, j) fixgef(i, j, lng)
96 : #define lngeq(i, j) fixeq(i, j, lng)
97 : #define lngnil(i) fixnil(i, lng)
98 : #define lngswap(i, j) fixswap(i, j, lng)
99 :
100 : #define hgeltf(i, j) fixltf(i, j, hge)
101 : #define hgelef(i, j) fixlef(i, j, hge)
102 : #define hgeltl(i, j) fixltl(i, j, hge)
103 : #define hgelel(i, j) fixlel(i, j, hge)
104 : #define hgeltl_rev(i, j) fixgtl(i, j, hge)
105 : #define hgelel_rev(i, j) fixgel(i, j, hge)
106 : #define hgeltf_rev(i, j) fixgtf(i, j, hge)
107 : #define hgelef_rev(i, j) fixgef(i, j, hge)
108 : #define hgeeq(i, j) fixeq(i, j, hge)
109 : #define hgenil(i) fixnil(i, hge)
110 : #define hgeswap(i, j) fixswap(i, j, hge)
111 :
112 : #define fltltf(i, j) (!fltnil(j) && (fltnil(i) || fixltf(i, j, flt)))
113 : #define fltlef(i, j) (fltnil(i) || (!fltnil(j) && fixlef(i, j, flt)))
114 : #define fltltl(i, j) fixltl(i, j, flt)
115 : #define fltlel(i, j) fixlel(i, j, flt)
116 : #define fltltl_rev(i, j) (!fltnil(i) && (fltnil(j) || fixgtl(i, j, flt)))
117 : #define fltlel_rev(i, j) (fltnil(j) || (!fltnil(i) && fixgel(i, j, flt)))
118 : #define fltltf_rev(i, j) fixgtf(i, j, flt)
119 : #define fltlef_rev(i, j) fixgef(i, j, flt)
120 : #define flteq(i, j) (fltnil(i) ? fltnil(j) : !fltnil(j) && fixeq(i, j, flt))
121 : #define fltnil(i) fixnil(i, flt)
122 : #define fltswap(i, j) fixswap(i, j, flt)
123 :
124 : #define dblltf(i, j) (!dblnil(j) && (dblnil(i) || fixltf(i, j, dbl)))
125 : #define dbllef(i, j) (dblnil(i) || (!dblnil(j) && fixlef(i, j, dbl)))
126 : #define dblltl(i, j) fixltl(i, j, dbl)
127 : #define dbllel(i, j) fixlel(i, j, dbl)
128 : #define dblltl_rev(i, j) (!dblnil(i) && (dblnil(j) || fixgtl(i, j, dbl)))
129 : #define dbllel_rev(i, j) (dblnil(j) || (!dblnil(i) && fixgel(i, j, dbl)))
130 : #define dblltf_rev(i, j) fixgtf(i, j, dbl)
131 : #define dbllef_rev(i, j) fixgef(i, j, dbl)
132 : #define dbleq(i, j) (dblnil(i) ? dblnil(j) : !dblnil(j) && fixeq(i, j, dbl))
133 : #define dblnil(i) fixnil(i, dbl)
134 : #define dblswap(i, j) fixswap(i, j, dbl)
135 :
136 : #define anyCMP(i, j) (*buf->cmp)(h + (i)*buf->hs, h + (j)*buf->hs)
137 : #define anyltf(i, j) (anyCMP(i, j) < 0)
138 : #define anylef(i, j) (anyCMP(i, j) <= 0)
139 : #define anyltl(i, j) (!anynil(i) && (anynil(j) || anyCMP(i, j) < 0))
140 : #define anylel(i, j) (anynil(j) || (!anynil(i) && anyCMP(i, j) <= 0))
141 : #define anyltl_rev(i, j) (anyCMP(i, j) > 0)
142 : #define anylel_rev(i, j) (anyCMP(i, j) >= 0)
143 : #define anyltf_rev(i, j) (!anynil(j) && (anynil(i) || anyCMP(i, j) > 0))
144 : #define anylef_rev(i, j) (anynil(i) || (!anynil(j) && anyCMP(i, j) >= 0))
145 : #define anyeq(i, j) (anyCMP(i, j) == 0)
146 : #define anynil(i) ((*buf->cmp)(h + (i)*buf->hs, buf->nil) == 0)
147 : #define anyswap(i, j) \
148 : do { \
149 : SWAP1((i) * buf->hs, (j) * buf->hs, h, buf->hs); \
150 : if (t) \
151 : SWAP1((i) * buf->ts, (j) * buf->ts, t, buf->ts); \
152 : } while (0)
153 :
154 : #define varOFF(i) (buf->base + VarHeapVal(h, i, buf->hs))
155 : #define varCMP(i, j) (*buf->cmp)(varOFF(i), varOFF(j))
156 : #define varltf(i, j) (varCMP(i, j) < 0)
157 : #define varlef(i, j) (varCMP(i, j) <= 0)
158 : #define varltl(i, j) (!varnil(i) && (varnil(j) || varCMP(i, j) < 0))
159 : #define varlel(i, j) (varnil(j) || (!varnil(i) && varCMP(i, j) <= 0))
160 : #define varltl_rev(i, j) (varCMP(i, j) > 0)
161 : #define varlel_rev(i, j) (varCMP(i, j) >= 0)
162 : #define varltf_rev(i, j) (!varnil(j) && (varnil(i) || varCMP(i, j) > 0))
163 : #define varlef_rev(i, j) (varnil(i) || (!varnil(j) && varCMP(i, j) >= 0))
164 : #define vareq(i, j) (varCMP(i, j) == 0)
165 : #define varnil(i) ((*buf->cmp)(varOFF(i), buf->nil) == 0)
166 : #define varswap(i, j) anyswap(i, j)
167 :
168 : #define LE(i, j, TPE, SUFF) CONCAT3(TPE, le, SUFF)(i, j)
169 : #define LT(i, j, TPE, SUFF) CONCAT3(TPE, lt, SUFF)(i, j)
170 : #define EQ(i, j, TPE) CONCAT2(TPE, eq)(i, j)
171 : #define SWAP(i, j, TPE) CONCAT2(TPE, swap)(i, j)
172 :
173 : /* return index of middle value at indexes a, b, and c */
174 : #define MED3(a, b, c, TPE, SUFF) (LT(a, b, TPE, SUFF) \
175 : ? (LT(b, c, TPE, SUFF) \
176 : ? (b) \
177 : : (LT(a, c, TPE, SUFF) \
178 : ? (c) \
179 : : (a))) \
180 : : (LT(c, b, TPE, SUFF) \
181 : ? (b) \
182 : : (LT(a, c, TPE, SUFF) \
183 : ? (a) \
184 : : (c))))
185 :
186 : /* generic swap: swap w bytes starting at indexes i and j with each
187 : * other from the array given by b */
188 : #define SWAP1(i, j, b, w) \
189 : do { \
190 : for (size_t _z = (w), _i = (i), _j = (j); _z > 0; _z--) { \
191 : char _tmp = b[_i]; \
192 : b[_i++] = b[_j]; \
193 : b[_j++] = _tmp; \
194 : } \
195 : } while (0)
196 : /* swap n items from both h and t arrays starting at indexes i and j */
197 : #define multi_SWAP(i, j, n) \
198 : do { \
199 : SWAP1((i) * buf->hs, (j) * buf->hs, h, n * buf->hs); \
200 : if (t) \
201 : SWAP1((i) * buf->ts, (j) * buf->ts, t, n * buf->ts); \
202 : } while (0)
203 :
204 : /* From here we define and redefine tokens and include the
205 : * implementation file multiple times to get versions for different
206 : * types and to get both ascending and descending (reverse) sort.
207 : * Note that for reverse sort, the LE (less or equal) and LT (less
208 : * than) macros are in fact greater or equal and greater than. */
209 :
210 : #define TPE bte
211 : #define SUFF f
212 : #include "gdk_qsort_impl.h"
213 : #undef SUFF
214 : #define SUFF l
215 : #include "gdk_qsort_impl.h"
216 : #undef SUFF
217 : #define SUFF l_rev
218 : #include "gdk_qsort_impl.h"
219 : #undef SUFF
220 : #define SUFF f_rev
221 : #include "gdk_qsort_impl.h"
222 : #undef SUFF
223 : #undef TPE
224 :
225 : #define TPE sht
226 : #define SUFF f
227 : #include "gdk_qsort_impl.h"
228 : #undef SUFF
229 : #define SUFF l
230 : #include "gdk_qsort_impl.h"
231 : #undef SUFF
232 : #define SUFF l_rev
233 : #include "gdk_qsort_impl.h"
234 : #undef SUFF
235 : #define SUFF f_rev
236 : #include "gdk_qsort_impl.h"
237 : #undef SUFF
238 : #undef TPE
239 :
240 : #define TPE int
241 : #define SUFF f
242 : #include "gdk_qsort_impl.h"
243 : #undef SUFF
244 : #define SUFF l
245 : #include "gdk_qsort_impl.h"
246 : #undef SUFF
247 : #define SUFF l_rev
248 : #include "gdk_qsort_impl.h"
249 : #undef SUFF
250 : #define SUFF f_rev
251 : #include "gdk_qsort_impl.h"
252 : #undef SUFF
253 : #undef TPE
254 :
255 : #define TPE lng
256 : #define SUFF f
257 : #include "gdk_qsort_impl.h"
258 : #undef SUFF
259 : #define SUFF l
260 : #include "gdk_qsort_impl.h"
261 : #undef SUFF
262 : #define SUFF l_rev
263 : #include "gdk_qsort_impl.h"
264 : #undef SUFF
265 : #define SUFF f_rev
266 : #include "gdk_qsort_impl.h"
267 : #undef SUFF
268 : #undef TPE
269 :
270 : #ifdef HAVE_HGE
271 : #define TPE hge
272 : #define SUFF f
273 : #include "gdk_qsort_impl.h"
274 : #undef SUFF
275 : #define SUFF l
276 : #include "gdk_qsort_impl.h"
277 : #undef SUFF
278 : #define SUFF l_rev
279 : #include "gdk_qsort_impl.h"
280 : #undef SUFF
281 : #define SUFF f_rev
282 : #include "gdk_qsort_impl.h"
283 : #undef SUFF
284 : #undef TPE
285 : #endif
286 :
287 : #define TPE flt
288 : #define SUFF f
289 : #include "gdk_qsort_impl.h"
290 : #undef SUFF
291 : #define SUFF l
292 : #include "gdk_qsort_impl.h"
293 : #undef SUFF
294 : #define SUFF l_rev
295 : #include "gdk_qsort_impl.h"
296 : #undef SUFF
297 : #define SUFF f_rev
298 : #include "gdk_qsort_impl.h"
299 : #undef SUFF
300 : #undef TPE
301 :
302 : #define TPE dbl
303 : #define SUFF f
304 : #include "gdk_qsort_impl.h"
305 : #undef SUFF
306 : #define SUFF l
307 : #include "gdk_qsort_impl.h"
308 : #undef SUFF
309 : #define SUFF l_rev
310 : #include "gdk_qsort_impl.h"
311 : #undef SUFF
312 : #define SUFF f_rev
313 : #include "gdk_qsort_impl.h"
314 : #undef SUFF
315 : #undef TPE
316 :
317 : #define TPE any
318 : #define SUFF f
319 : #include "gdk_qsort_impl.h"
320 : #undef SUFF
321 : #define SUFF l
322 : #include "gdk_qsort_impl.h"
323 : #undef SUFF
324 : #define SUFF l_rev
325 : #include "gdk_qsort_impl.h"
326 : #undef SUFF
327 : #define SUFF f_rev
328 : #include "gdk_qsort_impl.h"
329 : #undef SUFF
330 : #undef TPE
331 :
332 : #define TPE var
333 : #define SUFF f
334 : #include "gdk_qsort_impl.h"
335 : #undef SUFF
336 : #define SUFF l
337 : #include "gdk_qsort_impl.h"
338 : #undef SUFF
339 : #define SUFF l_rev
340 : #include "gdk_qsort_impl.h"
341 : #undef SUFF
342 : #define SUFF f_rev
343 : #include "gdk_qsort_impl.h"
344 : #undef SUFF
345 : #undef TPE
346 :
347 : /* Sort the array `h' of `n' elements with size `hs' each and type
348 : * `ts' in ascending or descending (if `reverse' is true) order. If
349 : * the type `tpe' indicates a variable-sized type, `h' contains
350 : * offsets into the `base' array which should be NULL otherwise. The
351 : * array `t', if not NULL, contains `n' values of size `ts' each which
352 : * will be moved around together with the corresponding elements in
353 : * `h' (i.e. `t' is the payload). If `nilslast' is true, nils sort at
354 : * the end, otherwise at the beginning of the result.
355 : *
356 : * This function uses a variant of quicksort and is thus not a stable
357 : * sort. */
358 : void
359 3172403 : GDKqsort(void *restrict h, void *restrict t, const void *restrict base,
360 : size_t n, int hs, int ts, int tpe, bool reverse, bool nilslast)
361 : {
362 3172403 : struct qsort_t buf;
363 :
364 3172403 : assert(hs > 0);
365 3172403 : assert(ts >= 0);
366 3172403 : assert(tpe != TYPE_void);
367 3172403 : assert((ts == 0) == (t == NULL));
368 :
369 3172403 : if (n <= 1)
370 95661 : return; /* nothing to do */
371 :
372 3115204 : buf.hs = (unsigned int) hs;
373 3115204 : buf.ts = (unsigned int) ts;
374 3115204 : buf.cmp = ATOMcompare(tpe);
375 3115204 : buf.base = base;
376 3115204 : buf.nil = ATOMnilptr(tpe);
377 3115204 : assert(ATOMvarsized(tpe) ? base != NULL : base == NULL);
378 :
379 3115204 : tpe = ATOMbasetype(tpe);
380 :
381 3115204 : if (reverse) {
382 371470 : if (nilslast) {
383 : /* "normal" descending sort order, i.e. with
384 : * NILs as smallest value, so they come
385 : * last */
386 371410 : if (ATOMvarsized(tpe)) {
387 97 : GDKqsort_impl_varl_rev(&buf, h, t, n);
388 97 : return;
389 : }
390 371313 : switch (tpe) {
391 1091 : case TYPE_bte:
392 1091 : GDKqsort_impl_btel_rev(&buf, h, t, n);
393 1091 : break;
394 9 : case TYPE_sht:
395 9 : GDKqsort_impl_shtl_rev(&buf, h, t, n);
396 9 : break;
397 369908 : case TYPE_int:
398 369908 : GDKqsort_impl_intl_rev(&buf, h, t, n);
399 369908 : break;
400 121 : case TYPE_lng:
401 121 : GDKqsort_impl_lngl_rev(&buf, h, t, n);
402 121 : break;
403 : #ifdef HAVE_HGE
404 160 : case TYPE_hge:
405 160 : GDKqsort_impl_hgel_rev(&buf, h, t, n);
406 160 : break;
407 : #endif
408 8 : case TYPE_flt:
409 8 : GDKqsort_impl_fltl_rev(&buf, h, t, n);
410 8 : break;
411 10 : case TYPE_dbl:
412 10 : GDKqsort_impl_dbll_rev(&buf, h, t, n);
413 10 : break;
414 6 : default:
415 6 : GDKqsort_impl_anyl_rev(&buf, h, t, n);
416 6 : break;
417 : }
418 : } else {
419 60 : if (ATOMvarsized(tpe)) {
420 10 : GDKqsort_impl_varf_rev(&buf, h, t, n);
421 10 : return;
422 : }
423 50 : switch (tpe) {
424 20 : case TYPE_bte:
425 20 : GDKqsort_impl_btef_rev(&buf, h, t, n);
426 20 : break;
427 0 : case TYPE_sht:
428 0 : GDKqsort_impl_shtf_rev(&buf, h, t, n);
429 0 : break;
430 4 : case TYPE_int:
431 4 : GDKqsort_impl_intf_rev(&buf, h, t, n);
432 4 : break;
433 18 : case TYPE_lng:
434 18 : GDKqsort_impl_lngf_rev(&buf, h, t, n);
435 18 : break;
436 : #ifdef HAVE_HGE
437 1 : case TYPE_hge:
438 1 : GDKqsort_impl_hgef_rev(&buf, h, t, n);
439 1 : break;
440 : #endif
441 4 : case TYPE_flt:
442 4 : GDKqsort_impl_fltf_rev(&buf, h, t, n);
443 4 : break;
444 3 : case TYPE_dbl:
445 3 : GDKqsort_impl_dblf_rev(&buf, h, t, n);
446 3 : break;
447 0 : default:
448 0 : GDKqsort_impl_anyf_rev(&buf, h, t, n);
449 0 : break;
450 : }
451 : }
452 : } else {
453 2743734 : if (nilslast) {
454 2131 : if (ATOMvarsized(tpe)) {
455 11 : GDKqsort_impl_varl(&buf, h, t, n);
456 11 : return;
457 : }
458 2120 : switch (tpe) {
459 29 : case TYPE_bte:
460 29 : GDKqsort_impl_btel(&buf, h, t, n);
461 29 : break;
462 0 : case TYPE_sht:
463 0 : GDKqsort_impl_shtl(&buf, h, t, n);
464 0 : break;
465 2057 : case TYPE_int:
466 2057 : GDKqsort_impl_intl(&buf, h, t, n);
467 2057 : break;
468 29 : case TYPE_lng:
469 29 : GDKqsort_impl_lngl(&buf, h, t, n);
470 29 : break;
471 : #ifdef HAVE_HGE
472 0 : case TYPE_hge:
473 0 : GDKqsort_impl_hgel(&buf, h, t, n);
474 0 : break;
475 : #endif
476 3 : case TYPE_flt:
477 3 : GDKqsort_impl_fltl(&buf, h, t, n);
478 3 : break;
479 2 : case TYPE_dbl:
480 2 : GDKqsort_impl_dbll(&buf, h, t, n);
481 2 : break;
482 0 : default:
483 0 : GDKqsort_impl_anyl(&buf, h, t, n);
484 0 : break;
485 : }
486 : } else {
487 : /* "normal" ascending sort order, i.e. with
488 : * NILs as smallest value, so they come
489 : * first */
490 2741603 : if (ATOMvarsized(tpe)) {
491 38344 : GDKqsort_impl_varf(&buf, h, t, n);
492 38344 : return;
493 : }
494 2703259 : switch (tpe) {
495 3075 : case TYPE_bte:
496 3075 : GDKqsort_impl_btef(&buf, h, t, n);
497 3075 : break;
498 933 : case TYPE_sht:
499 933 : GDKqsort_impl_shtf(&buf, h, t, n);
500 933 : break;
501 2692242 : case TYPE_int:
502 2692242 : GDKqsort_impl_intf(&buf, h, t, n);
503 2692242 : break;
504 5430 : case TYPE_lng:
505 5430 : GDKqsort_impl_lngf(&buf, h, t, n);
506 5430 : break;
507 : #ifdef HAVE_HGE
508 1408 : case TYPE_hge:
509 1408 : GDKqsort_impl_hgef(&buf, h, t, n);
510 1408 : break;
511 : #endif
512 24 : case TYPE_flt:
513 24 : GDKqsort_impl_fltf(&buf, h, t, n);
514 24 : break;
515 143 : case TYPE_dbl:
516 143 : GDKqsort_impl_dblf(&buf, h, t, n);
517 143 : break;
518 4 : default:
519 4 : GDKqsort_impl_anyf(&buf, h, t, n);
520 4 : break;
521 : }
522 : }
523 : }
524 : }
|