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