skidd13@9520: /* $Id$ */ skidd13@9520: skidd13@9520: /** @file sort_func.hpp Functions related to sorting operations. */ skidd13@9520: skidd13@9520: #ifndef SORT_FUNC_HPP skidd13@9520: #define SORT_FUNC_HPP skidd13@9520: skidd13@9520: #include skidd13@9520: #include "math_func.hpp" skidd13@9520: #include "mem_func.hpp" skidd13@9520: skidd13@9520: /** skidd13@9520: * Type safe qsort() skidd13@9520: * skidd13@9520: * @todo replace the normal qsort with this one skidd13@9520: * @note Use this sort for irregular sorted data. skidd13@9520: * skidd13@9520: * @param base Pointer to the first element of the array to be sorted. skidd13@9520: * @param num Number of elements in the array pointed by base. skidd13@9520: * @param comparator Function that compares two elements. skidd13@9520: * @param desc Sort descending. skidd13@9520: */ skidd13@9575: template skidd13@9575: static FORCEINLINE void QSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false) skidd13@9520: { skidd13@9520: if (num < 2) return; skidd13@9520: skidd13@9520: qsort(base, num, sizeof(T), (int (CDECL *)(const void *, const void *))comparator); skidd13@9520: skidd13@9520: if (desc) MemReverseT(base, num); skidd13@9520: } skidd13@9520: skidd13@9520: /** skidd13@9520: * Type safe Gnome Sort. skidd13@9520: * skidd13@9520: * This is a slightly modifyied Gnome search. The basic skidd13@9520: * Gnome search trys to sort already sorted list parts. skidd13@9520: * The modification skips these. skidd13@9520: * skidd13@9520: * @note Use this sort for presorted / regular sorted data. skidd13@9520: * skidd13@9520: * @param base Pointer to the first element of the array to be sorted. skidd13@9520: * @param num Number of elements in the array pointed by base. skidd13@9520: * @param comparator Function that compares two elements. skidd13@9520: * @param desc Sort descending. skidd13@9520: */ skidd13@9575: template skidd13@9575: static inline void GSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false) skidd13@9520: { skidd13@9520: if (num < 2) return; skidd13@9520: skidd13@9520: assert(base != NULL); skidd13@9520: assert(comparator != NULL); skidd13@9520: skidd13@9520: T *a = base; skidd13@9520: T *b = base + 1; skidd13@9520: uint offset = 0; skidd13@9520: skidd13@9520: while (num > 1) { skidd13@9520: const int diff = comparator(a, b); skidd13@9520: if ((!desc && diff <= 0) || (desc && diff >= 0)) { skidd13@9520: if (offset != 0) { skidd13@9520: /* Jump back to the last direction switch point */ skidd13@9520: a += offset; skidd13@9520: b += offset; skidd13@9520: offset = 0; skidd13@9520: continue; skidd13@9520: } skidd13@9520: skidd13@9520: a++; skidd13@9520: b++; skidd13@9520: num--; skidd13@9520: } else { skidd13@9520: Swap(*a, *b); skidd13@9520: skidd13@9520: if (a == base) continue; skidd13@9520: skidd13@9520: a--; skidd13@9520: b--; skidd13@9520: offset++; skidd13@9520: } skidd13@9520: } skidd13@9520: } skidd13@9520: skidd13@9520: #endif /* SORT_FUNC_HPP */