1+ /* -----------------------------------------------------------------------------------------------
2+ The MIT License (MIT)
3+
4+ Copyright (c) 2014-2025 Kim Kulling
5+
6+ Permission is hereby granted, free of charge, to any person obtaining a copy of
7+ this software and associated documentation files (the "Software"), to deal in
8+ the Software without restriction, including without limitation the rights to
9+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10+ the Software, and to permit persons to whom the Software is furnished to do so,
11+ subject to the following conditions:
12+
13+ The above copyright notice and this permission notice shall be included in all
14+ copies or substantial portions of the Software.
15+
16+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+ -----------------------------------------------------------------------------------------------*/
123#pragma once
224
325#include < cppcore/CPPCoreCommon.h>
@@ -7,12 +29,24 @@ namespace cppcore {
729 typedef int32_t (*ComparisonFn)(const void * _lhs, const void * _rhs);
830
931 template <class T >
10- int32_t compAscending (const void *lhs, const void *rhs) {
32+ inline int32_t compAscending (const void *lhs, const void *rhs) {
1133 const T _lhs = *static_cast <const T *>(lhs);
1234 const T _rhs = *static_cast <const T *>(rhs);
1335 return (_lhs > _rhs) - (_lhs < _rhs);
1436 }
1537
38+ template <typename Ty>
39+ inline int32_t compDescending (const void *_lhs, const void *_rhs) {
40+ return compAscending<Ty>(_rhs, _lhs);
41+ }
42+
43+ template <class T >
44+ inline void swap (T& v1, T& v2) {
45+ T tmp = v1;
46+ v1 = v2;
47+ v2 = tmp;
48+ }
49+
1650 inline void swap (uint8_t &lhs, uint8_t &rhs) {
1751 uint8_t tmp = lhs;
1852 lhs = rhs;
@@ -28,7 +62,7 @@ namespace cppcore {
2862 }
2963 }
3064
31- inline void quicksort (void *pivot, void *_data, size_t num, size_t stride, ComparisonFn func) {
65+ inline void quicksortImpl (void *pivot, void *_data, size_t num, size_t stride, ComparisonFn func) {
3266 if (num < 2 ) {
3367 return ;
3468 }
@@ -37,11 +71,13 @@ namespace cppcore {
3771 return ;
3872 }
3973
74+ uint8_t *data = (uint8_t *) _data;
75+ memcpy (pivot, &data[0 ], stride);
76+
4077 size_t l = 0 ;
4178 size_t g = 1 ;
42- uint8_t *data = (uint8_t *) _data;
4379 for (size_t i=1 ; i<num;) {
44- int32_t result = func (&data[i], pivot);
80+ int32_t result = func (&data[i*stride ], pivot);
4581 if (result > 0 ) {
4682 swap (&data[l*stride], &data[i*stride], stride);
4783 ++l;
@@ -54,8 +90,13 @@ namespace cppcore {
5490 }
5591 }
5692
57- quicksort (pivot, &data[0 ], l, stride, func);
58- quicksort (pivot, &data[g], num - g, stride, func);
93+ quicksortImpl (pivot, &data[0 ], l, stride, func);
94+ quicksortImpl (pivot, &data[g*stride], num - g, stride, func);
95+ }
96+
97+ inline void quicksort (void *_data, size_t num, size_t stride, ComparisonFn func) {
98+ uint8_t *pivot = (uint8_t *) CPPCORE_STACK_ALLOC (stride);
99+ quicksortImpl (pivot, _data, num, stride, func);
59100 }
60101
61102 bool isSorted (const void *data, size_t num, size_t stride, ComparisonFn func) {
0 commit comments