src/core/sort_func.hpp
branchNewGRF_ports
changeset 10994 cd9968b6f96b
child 11049 f8bbc9635251
equal deleted inserted replaced
10991:d8811e327d12 10994:cd9968b6f96b
       
     1 /* $Id$ */
       
     2 
       
     3 /** @file sort_func.hpp Functions related to sorting operations. */
       
     4 
       
     5 #ifndef SORT_FUNC_HPP
       
     6 #define SORT_FUNC_HPP
       
     7 
       
     8 #include <stdlib.h>
       
     9 #include "math_func.hpp"
       
    10 #include "mem_func.hpp"
       
    11 
       
    12 /**
       
    13  * Type safe qsort()
       
    14  *
       
    15  * @todo replace the normal qsort with this one
       
    16  * @note Use this sort for irregular sorted data.
       
    17  *
       
    18  * @param base Pointer to the first element of the array to be sorted.
       
    19  * @param num Number of elements in the array pointed by base.
       
    20  * @param comparator Function that compares two elements.
       
    21  * @param desc Sort descending.
       
    22  */
       
    23 template<typename T>
       
    24 FORCEINLINE void QSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false)
       
    25 {
       
    26 	if (num < 2) return;
       
    27 
       
    28 	qsort(base, num, sizeof(T), (int (CDECL *)(const void *, const void *))comparator);
       
    29 
       
    30 	if (desc) MemReverseT(base, num);
       
    31 }
       
    32 
       
    33 /**
       
    34  * Type safe Gnome Sort.
       
    35  *
       
    36  * This is a slightly modifyied Gnome search. The basic
       
    37  * Gnome search trys to sort already sorted list parts.
       
    38  * The modification skips these.
       
    39  *
       
    40  * @note Use this sort for presorted / regular sorted data.
       
    41  *
       
    42  * @param base Pointer to the first element of the array to be sorted.
       
    43  * @param num Number of elements in the array pointed by base.
       
    44  * @param comparator Function that compares two elements.
       
    45  * @param desc Sort descending.
       
    46  */
       
    47 template<typename T>
       
    48 FORCEINLINE void GSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false)
       
    49 {
       
    50 	if (num < 2) return;
       
    51 
       
    52 	assert(base != NULL);
       
    53 	assert(comparator != NULL);
       
    54 
       
    55 	T *a = base;
       
    56 	T *b = base + 1;
       
    57 	uint offset = 0;
       
    58 
       
    59 	while (num > 1) {
       
    60 		const int diff = comparator(a, b);
       
    61 		if ((!desc && diff <= 0) || (desc && diff >= 0)) {
       
    62 			if (offset != 0) {
       
    63 				/* Jump back to the last direction switch point */
       
    64 				a += offset;
       
    65 				b += offset;
       
    66 				offset = 0;
       
    67 				continue;
       
    68 			}
       
    69 
       
    70 			a++;
       
    71 			b++;
       
    72 			num--;
       
    73 		} else {
       
    74 			Swap(*a, *b);
       
    75 
       
    76 			if (a == base) continue;
       
    77 
       
    78 			a--;
       
    79 			b--;
       
    80 			offset++;
       
    81 		}
       
    82 	}
       
    83 }
       
    84 
       
    85 #endif /* SORT_FUNC_HPP */