1 //===-- Implementation header for qsort utilities ---------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC_STDLIB_QUICK_SORT_H
10 #define LLVM_LIBC_SRC_STDLIB_QUICK_SORT_H
12 #include "src/__support/macros/attributes.h"
13 #include "src/__support/macros/config.h"
14 #include "src/stdlib/qsort_data.h"
18 namespace LIBC_NAMESPACE_DECL
{
21 // A simple quicksort implementation using the Hoare partition scheme.
22 LIBC_INLINE
size_t partition(const Array
&array
) {
23 const size_t array_size
= array
.size();
24 size_t pivot_index
= array_size
/ 2;
25 uint8_t *pivot
= array
.get(pivot_index
);
27 size_t j
= array_size
- 1;
30 int compare_i
, compare_j
;
32 while ((compare_i
= array
.elem_compare(i
, pivot
)) < 0)
34 while ((compare_j
= array
.elem_compare(j
, pivot
)) > 0)
37 // At some point i will crossover j so we will definitely break out of
44 // The pivot itself might have got swapped so we will update the pivot.
45 if (i
== pivot_index
) {
48 } else if (j
== pivot_index
) {
53 if (compare_i
== 0 && compare_j
== 0) {
54 // If we do not move the pointers, we will end up with an
55 // infinite loop as i and j will be stuck without advancing.
62 LIBC_INLINE
void quick_sort(Array array
) {
64 const size_t array_size
= array
.size();
67 size_t split_index
= partition(array
);
69 // The partition operation sorts the two element array.
72 // Make Arrays describing the two sublists that still need sorting.
73 Array left
= array
.make_array(0, split_index
);
74 Array right
= array
.make_array(split_index
, array
.size() - split_index
);
76 // Recurse to sort the smaller of the two, and then loop round within this
77 // function to sort the larger. This way, recursive call depth is bounded
78 // by log2 of the total array size, because every recursive call is sorting
79 // a list at most half the length of the one in its caller.
80 if (left
.size() < right
.size()) {
82 array
.reset_bounds(right
.get(0), right
.size());
85 array
.reset_bounds(left
.get(0), left
.size());
90 } // namespace internal
91 } // namespace LIBC_NAMESPACE_DECL
93 #endif // LLVM_LIBC_SRC_STDLIB_QUICK_SORT_H