summaryrefslogtreecommitdiff
path: root/libc/src/stdlib/qsort_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'libc/src/stdlib/qsort_util.h')
-rw-r--r--libc/src/stdlib/qsort_util.h47
1 files changed, 42 insertions, 5 deletions
diff --git a/libc/src/stdlib/qsort_util.h b/libc/src/stdlib/qsort_util.h
index d42adde06d97..7882b829d327 100644
--- a/libc/src/stdlib/qsort_util.h
+++ b/libc/src/stdlib/qsort_util.h
@@ -27,11 +27,48 @@
namespace LIBC_NAMESPACE_DECL {
namespace internal {
-#if LIBC_QSORT_IMPL == LIBC_QSORT_QUICK_SORT
-constexpr auto sort = quick_sort;
-#elif LIBC_QSORT_IMPL == LIBC_QSORT_HEAP_SORT
-constexpr auto sort = heap_sort;
-#endif
+template <bool USE_QUICKSORT, typename F>
+LIBC_INLINE void unstable_sort_impl(void *array, size_t array_len,
+ size_t elem_size, const F &is_less) {
+ if (array == nullptr || array_len == 0 || elem_size == 0)
+ return;
+
+ if constexpr (USE_QUICKSORT) {
+ switch (elem_size) {
+ case 4: {
+ auto arr_fixed_size = internal::ArrayFixedSize<4>(array, array_len);
+ quick_sort(arr_fixed_size, is_less);
+ return;
+ }
+ case 8: {
+ auto arr_fixed_size = internal::ArrayFixedSize<8>(array, array_len);
+ quick_sort(arr_fixed_size, is_less);
+ return;
+ }
+ case 16: {
+ auto arr_fixed_size = internal::ArrayFixedSize<16>(array, array_len);
+ quick_sort(arr_fixed_size, is_less);
+ return;
+ }
+ default:
+ auto arr_generic_size =
+ internal::ArrayGenericSize(array, array_len, elem_size);
+ quick_sort(arr_generic_size, is_less);
+ return;
+ }
+ } else {
+ auto arr_generic_size =
+ internal::ArrayGenericSize(array, array_len, elem_size);
+ heap_sort(arr_generic_size, is_less);
+ }
+}
+
+template <typename F>
+LIBC_INLINE void unstable_sort(void *array, size_t array_len, size_t elem_size,
+ const F &is_less) {
+#define USE_QUICK_SORT ((LIBC_QSORT_IMPL) == (LIBC_QSORT_QUICK_SORT))
+ unstable_sort_impl<USE_QUICK_SORT, F>(array, array_len, elem_size, is_less);
+}
} // namespace internal
} // namespace LIBC_NAMESPACE_DECL