/* * UCW Library -- Universal Simple Array Sorter * * (c) 2003--2008 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. */ #pragma once #include "contrib/macros.h" /* * This is not a normal header file, it's a generator of sorting * routines. Each time you include it with parameters set in the * corresponding preprocessor macros, it generates an array sorter * with the parameters given. * * You might wonder why the heck do we implement our own array sorter * instead of using qsort(). The primary reason is that qsort handles * only continuous arrays, but we need to sort array-like data structures * where the only way to access elements is by using an indexing macro. * Besides that, we are more than 2 times faster. * * So much for advocacy, there are the parameters (those marked with [*] * are mandatory): * * ASORT_PREFIX(x) [*] add a name prefix (used on all global names * defined by the sorter) * ASORT_KEY_TYPE [*] data type of a single array entry key * ASORT_ELT(i) returns the key of i-th element; if this macro is not * defined, the function gets a pointer to an array to be sorted * ASORT_LT(x,y) x < y for ASORT_KEY_TYPE (default: "x= ASORT_THRESHOLD && (right - l) >= ASORT_THRESHOLD) { /* Both partitions ok => push the larger one */ if ((r - left) > (right - l)) { stack[sp].l = left; stack[sp].r = r; left = l; } else { stack[sp].l = l; stack[sp].r = right; right = r; } sp++; } else if ((r - left) >= ASORT_THRESHOLD) { /* Left partition OK, right undersize */ right = r; } else if ((right - l) >= ASORT_THRESHOLD) { /* Right partition OK, left undersize */ left = l; } else { /* Both partitions undersize => pop */ if (!sp) break; sp--; left = stack[sp].l; right = stack[sp].r; } } /* * We have a partially sorted array, finish by insertsort. Inspired * by qsort() in GNU libc. */ /* Find minimal element which will serve as a barrier */ r = MIN(array_size, ASORT_THRESHOLD); m = 0; for (l=1; l