xref: /llvm-project/libc/src/stdlib/qsort_util.h (revision a738d81cd2822698539b0482af48d49d91ea5a2e)
1d3074f16SMichael Jones //===-- Implementation header for qsort utilities ---------------*- C++ -*-===//
2d3074f16SMichael Jones //
3d3074f16SMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d3074f16SMichael Jones // See https://llvm.org/LICENSE.txt for license information.
5d3074f16SMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d3074f16SMichael Jones //
7d3074f16SMichael Jones //===----------------------------------------------------------------------===//
8d3074f16SMichael Jones 
9d3074f16SMichael Jones #ifndef LLVM_LIBC_SRC_STDLIB_QSORT_UTIL_H
10d3074f16SMichael Jones #define LLVM_LIBC_SRC_STDLIB_QSORT_UTIL_H
11d3074f16SMichael Jones 
12a6d2da8bSlntue #include "src/stdlib/heap_sort.h"
13a6d2da8bSlntue #include "src/stdlib/quick_sort.h"
14a6d2da8bSlntue 
15a6d2da8bSlntue #define LIBC_QSORT_QUICK_SORT 1
16a6d2da8bSlntue #define LIBC_QSORT_HEAP_SORT 2
17a6d2da8bSlntue 
18a6d2da8bSlntue #ifndef LIBC_QSORT_IMPL
19a6d2da8bSlntue #define LIBC_QSORT_IMPL LIBC_QSORT_QUICK_SORT
20a6d2da8bSlntue #endif // LIBC_QSORT_IMPL
21a6d2da8bSlntue 
22a6d2da8bSlntue #if (LIBC_QSORT_IMPL != LIBC_QSORT_QUICK_SORT &&                               \
23a6d2da8bSlntue      LIBC_QSORT_IMPL != LIBC_QSORT_HEAP_SORT)
24a6d2da8bSlntue #error "LIBC_QSORT_IMPL is not recognized."
25a6d2da8bSlntue #endif
26d3074f16SMichael Jones 
275ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
285ff3ff33SPetr Hosek namespace internal {
29d3074f16SMichael Jones 
30*a738d81cSLukas Bergdoll template <bool USE_QUICKSORT, typename F>
31*a738d81cSLukas Bergdoll LIBC_INLINE void unstable_sort_impl(void *array, size_t array_len,
32*a738d81cSLukas Bergdoll                                     size_t elem_size, const F &is_less) {
33*a738d81cSLukas Bergdoll   if (array == nullptr || array_len == 0 || elem_size == 0)
34*a738d81cSLukas Bergdoll     return;
35*a738d81cSLukas Bergdoll 
36*a738d81cSLukas Bergdoll   if constexpr (USE_QUICKSORT) {
37*a738d81cSLukas Bergdoll     switch (elem_size) {
38*a738d81cSLukas Bergdoll     case 4: {
39*a738d81cSLukas Bergdoll       auto arr_fixed_size = internal::ArrayFixedSize<4>(array, array_len);
40*a738d81cSLukas Bergdoll       quick_sort(arr_fixed_size, is_less);
41*a738d81cSLukas Bergdoll       return;
42*a738d81cSLukas Bergdoll     }
43*a738d81cSLukas Bergdoll     case 8: {
44*a738d81cSLukas Bergdoll       auto arr_fixed_size = internal::ArrayFixedSize<8>(array, array_len);
45*a738d81cSLukas Bergdoll       quick_sort(arr_fixed_size, is_less);
46*a738d81cSLukas Bergdoll       return;
47*a738d81cSLukas Bergdoll     }
48*a738d81cSLukas Bergdoll     case 16: {
49*a738d81cSLukas Bergdoll       auto arr_fixed_size = internal::ArrayFixedSize<16>(array, array_len);
50*a738d81cSLukas Bergdoll       quick_sort(arr_fixed_size, is_less);
51*a738d81cSLukas Bergdoll       return;
52*a738d81cSLukas Bergdoll     }
53*a738d81cSLukas Bergdoll     default:
54*a738d81cSLukas Bergdoll       auto arr_generic_size =
55*a738d81cSLukas Bergdoll           internal::ArrayGenericSize(array, array_len, elem_size);
56*a738d81cSLukas Bergdoll       quick_sort(arr_generic_size, is_less);
57*a738d81cSLukas Bergdoll       return;
58*a738d81cSLukas Bergdoll     }
59*a738d81cSLukas Bergdoll   } else {
60*a738d81cSLukas Bergdoll     auto arr_generic_size =
61*a738d81cSLukas Bergdoll         internal::ArrayGenericSize(array, array_len, elem_size);
62*a738d81cSLukas Bergdoll     heap_sort(arr_generic_size, is_less);
63*a738d81cSLukas Bergdoll   }
64*a738d81cSLukas Bergdoll }
65*a738d81cSLukas Bergdoll 
66*a738d81cSLukas Bergdoll template <typename F>
67*a738d81cSLukas Bergdoll LIBC_INLINE void unstable_sort(void *array, size_t array_len, size_t elem_size,
68*a738d81cSLukas Bergdoll                                const F &is_less) {
69*a738d81cSLukas Bergdoll #define USE_QUICK_SORT ((LIBC_QSORT_IMPL) == (LIBC_QSORT_QUICK_SORT))
70*a738d81cSLukas Bergdoll   unstable_sort_impl<USE_QUICK_SORT, F>(array, array_len, elem_size, is_less);
71*a738d81cSLukas Bergdoll }
72d3074f16SMichael Jones 
735ff3ff33SPetr Hosek } // namespace internal
745ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
75d3074f16SMichael Jones 
76d3074f16SMichael Jones #endif // LLVM_LIBC_SRC_STDLIB_QSORT_UTIL_H
77