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