src/core/sort_func.hpp
author terom@frrb.lan
Fri, 19 Dec 2008 01:32:07 +0200
changeset 10438 51bff16a04c9
parent 9575 58d55b1a70c9
permissions -rw-r--r--
initial mini-map stuff
9520
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     1
/* $Id$ */
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     2
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     3
/** @file sort_func.hpp Functions related to sorting operations. */
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     4
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     5
#ifndef SORT_FUNC_HPP
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     6
#define SORT_FUNC_HPP
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     7
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     8
#include <stdlib.h>
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
     9
#include "math_func.hpp"
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    10
#include "mem_func.hpp"
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    11
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    12
/**
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    13
 * Type safe qsort()
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    14
 *
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    15
 * @todo replace the normal qsort with this one
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    16
 * @note Use this sort for irregular sorted data.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    17
 *
f08d9fc662a6 (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.
f08d9fc662a6 (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.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    20
 * @param comparator Function that compares two elements.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    21
 * @param desc Sort descending.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    22
 */
9575
58d55b1a70c9 (svn r13606) -Codechange: use "static FORCEINLINE" where possible as default for core functions (big functions use just inline instead)
skidd13
parents: 9520
diff changeset
    23
template <typename T>
58d55b1a70c9 (svn r13606) -Codechange: use "static FORCEINLINE" where possible as default for core functions (big functions use just inline instead)
skidd13
parents: 9520
diff changeset
    24
static FORCEINLINE void QSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false)
9520
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    25
{
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    26
	if (num < 2) return;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    27
f08d9fc662a6 (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);
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    29
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    30
	if (desc) MemReverseT(base, num);
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    31
}
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    32
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    33
/**
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    34
 * Type safe Gnome Sort.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    35
 *
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    36
 * This is a slightly modifyied Gnome search. The basic
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    37
 * Gnome search trys to sort already sorted list parts.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    38
 * The modification skips these.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    39
 *
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    40
 * @note Use this sort for presorted / regular sorted data.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    41
 *
f08d9fc662a6 (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.
f08d9fc662a6 (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.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    44
 * @param comparator Function that compares two elements.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    45
 * @param desc Sort descending.
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    46
 */
9575
58d55b1a70c9 (svn r13606) -Codechange: use "static FORCEINLINE" where possible as default for core functions (big functions use just inline instead)
skidd13
parents: 9520
diff changeset
    47
template <typename T>
58d55b1a70c9 (svn r13606) -Codechange: use "static FORCEINLINE" where possible as default for core functions (big functions use just inline instead)
skidd13
parents: 9520
diff changeset
    48
static inline void GSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false)
9520
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    49
{
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    50
	if (num < 2) return;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    51
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    52
	assert(base != NULL);
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    53
	assert(comparator != NULL);
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    54
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    55
	T *a = base;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    56
	T *b = base + 1;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    57
	uint offset = 0;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    58
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    59
	while (num > 1) {
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    60
		const int diff = comparator(a, b);
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    61
		if ((!desc && diff <= 0) || (desc && diff >= 0)) {
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    62
			if (offset != 0) {
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    63
				/* Jump back to the last direction switch point */
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    64
				a += offset;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    65
				b += offset;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    66
				offset = 0;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    67
				continue;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    68
			}
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    69
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    70
			a++;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    71
			b++;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    72
			num--;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    73
		} else {
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    74
			Swap(*a, *b);
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    75
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    76
			if (a == base) continue;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    77
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    78
			a--;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    79
			b--;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    80
			offset++;
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    81
		}
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    82
	}
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    83
}
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    84
f08d9fc662a6 (svn r13516) -Codechange: Move MemCpyT to a fitting core header
skidd13
parents:
diff changeset
    85
#endif /* SORT_FUNC_HPP */