1 //===----------------------------------------------------------------------===//
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 _LIBCPP___ALGORITHM_SORT_H
10 #define _LIBCPP___ALGORITHM_SORT_H
12 #include <__algorithm/comp.h>
13 #include <__algorithm/comp_ref_type.h>
14 #include <__algorithm/iter_swap.h>
15 #include <__algorithm/iterator_operations.h>
16 #include <__algorithm/min_element.h>
17 #include <__algorithm/partial_sort.h>
18 #include <__algorithm/unwrap_iter.h>
20 #include <__bit/blsr.h>
21 #include <__bit/countl.h>
22 #include <__bit/countr.h>
24 #include <__debug_utils/randomize_range.h>
25 #include <__debug_utils/strict_weak_ordering_check.h>
26 #include <__functional/operations.h>
27 #include <__functional/ranges_operations.h>
28 #include <__iterator/iterator_traits.h>
29 #include <__type_traits/conditional.h>
30 #include <__type_traits/disjunction.h>
31 #include <__type_traits/is_arithmetic.h>
32 #include <__type_traits/is_constant_evaluated.h>
33 #include <__utility/move.h>
34 #include <__utility/pair.h>
38 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
39 # pragma GCC system_header
42 _LIBCPP_BEGIN_NAMESPACE_STD
44 // stable, 2-3 compares, 0-2 swaps
46 template <class _AlgPolicy
, class _Compare
, class _ForwardIterator
>
48 _LIBCPP_CONSTEXPR_SINCE_CXX14
unsigned __sort3(_ForwardIterator __x
, _ForwardIterator __y
, _ForwardIterator __z
,
50 using _Ops
= _IterOps
<_AlgPolicy
>;
53 if (!__c(*__y
, *__x
)) // if x <= y
55 if (!__c(*__z
, *__y
)) // if y <= z
56 return __r
; // x <= y && y <= z
58 _Ops::iter_swap(__y
, __z
); // x <= z && y < z
60 if (__c(*__y
, *__x
)) // if x > y
62 _Ops::iter_swap(__x
, __y
); // x < y && y <= z
65 return __r
; // x <= y && y < z
67 if (__c(*__z
, *__y
)) // x > y, if y > z
69 _Ops::iter_swap(__x
, __z
); // x < y && y < z
73 _Ops::iter_swap(__x
, __y
); // x > y && y <= z
74 __r
= 1; // x < y && x <= z
75 if (__c(*__z
, *__y
)) // if y > z
77 _Ops::iter_swap(__y
, __z
); // x <= y && y < z
83 // stable, 3-6 compares, 0-5 swaps
85 template <class _AlgPolicy
, class _Compare
, class _ForwardIterator
>
87 void __sort4(_ForwardIterator __x1
, _ForwardIterator __x2
, _ForwardIterator __x3
, _ForwardIterator __x4
,
89 using _Ops
= _IterOps
<_AlgPolicy
>;
90 std::__sort3
<_AlgPolicy
, _Compare
>(__x1
, __x2
, __x3
, __c
);
91 if (__c(*__x4
, *__x3
)) {
92 _Ops::iter_swap(__x3
, __x4
);
93 if (__c(*__x3
, *__x2
)) {
94 _Ops::iter_swap(__x2
, __x3
);
95 if (__c(*__x2
, *__x1
)) {
96 _Ops::iter_swap(__x1
, __x2
);
102 // stable, 4-10 compares, 0-9 swaps
104 template <class _AlgPolicy
, class _Comp
, class _ForwardIterator
>
105 _LIBCPP_HIDE_FROM_ABI
void __sort5(_ForwardIterator __x1
, _ForwardIterator __x2
, _ForwardIterator __x3
,
106 _ForwardIterator __x4
, _ForwardIterator __x5
, _Comp __comp
) {
107 using _Ops
= _IterOps
<_AlgPolicy
>;
109 std::__sort4
<_AlgPolicy
, _Comp
>(__x1
, __x2
, __x3
, __x4
, __comp
);
110 if (__comp(*__x5
, *__x4
)) {
111 _Ops::iter_swap(__x4
, __x5
);
112 if (__comp(*__x4
, *__x3
)) {
113 _Ops::iter_swap(__x3
, __x4
);
114 if (__comp(*__x3
, *__x2
)) {
115 _Ops::iter_swap(__x2
, __x3
);
116 if (__comp(*__x2
, *__x1
)) {
117 _Ops::iter_swap(__x1
, __x2
);
124 // The comparator being simple is a prerequisite for using the branchless optimization.
126 struct __is_simple_comparator
: false_type
{};
128 struct __is_simple_comparator
<__less
<>&> : true_type
{};
130 struct __is_simple_comparator
<less
<_Tp
>&> : true_type
{};
132 struct __is_simple_comparator
<greater
<_Tp
>&> : true_type
{};
133 #if _LIBCPP_STD_VER >= 20
135 struct __is_simple_comparator
<ranges::less
&> : true_type
{};
137 struct __is_simple_comparator
<ranges::greater
&> : true_type
{};
140 template <class _Compare
, class _Iter
, class _Tp
= typename iterator_traits
<_Iter
>::value_type
>
141 using __use_branchless_sort
=
142 integral_constant
<bool, __libcpp_is_contiguous_iterator
<_Iter
>::value
&& sizeof(_Tp
) <= sizeof(void*) &&
143 is_arithmetic
<_Tp
>::value
&& __is_simple_comparator
<_Compare
>::value
>;
147 // Size in bits for the bitset in use.
148 enum { __block_size
= sizeof(uint64_t) * 8 };
150 } // namespace __detail
152 // Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary.
153 template <class _Compare
, class _RandomAccessIterator
>
154 inline _LIBCPP_HIDE_FROM_ABI
void __cond_swap(_RandomAccessIterator __x
, _RandomAccessIterator __y
, _Compare __c
) {
155 // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`).
156 using value_type
= typename iterator_traits
<_RandomAccessIterator
>::value_type
;
157 bool __r
= __c(*__x
, *__y
);
158 value_type __tmp
= __r
? *__x
: *__y
;
159 *__y
= __r
? *__y
: *__x
;
163 // Ensures that *__x, *__y and *__z are ordered according to the comparator __c,
164 // under the assumption that *__y and *__z are already ordered.
165 template <class _Compare
, class _RandomAccessIterator
>
166 inline _LIBCPP_HIDE_FROM_ABI
void __partially_sorted_swap(_RandomAccessIterator __x
, _RandomAccessIterator __y
,
167 _RandomAccessIterator __z
, _Compare __c
) {
168 // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`).
169 using value_type
= typename iterator_traits
<_RandomAccessIterator
>::value_type
;
170 bool __r
= __c(*__z
, *__x
);
171 value_type __tmp
= __r
? *__z
: *__x
;
172 *__z
= __r
? *__x
: *__z
;
173 __r
= __c(__tmp
, *__y
);
174 *__x
= __r
? *__x
: *__y
;
175 *__y
= __r
? *__y
: __tmp
;
178 template <class, class _Compare
, class _RandomAccessIterator
,
179 __enable_if_t
<__use_branchless_sort
<_Compare
, _RandomAccessIterator
>::value
, int> = 0>
180 inline _LIBCPP_HIDE_FROM_ABI
void
181 __sort3_maybe_branchless(_RandomAccessIterator __x1
, _RandomAccessIterator __x2
, _RandomAccessIterator __x3
,
183 std::__cond_swap
<_Compare
>(__x2
, __x3
, __c
);
184 std::__partially_sorted_swap
<_Compare
>(__x1
, __x2
, __x3
, __c
);
187 template <class _AlgPolicy
, class _Compare
, class _RandomAccessIterator
,
188 __enable_if_t
<!__use_branchless_sort
<_Compare
, _RandomAccessIterator
>::value
, int> = 0>
189 inline _LIBCPP_HIDE_FROM_ABI
void
190 __sort3_maybe_branchless(_RandomAccessIterator __x1
, _RandomAccessIterator __x2
, _RandomAccessIterator __x3
,
192 std::__sort3
<_AlgPolicy
, _Compare
>(__x1
, __x2
, __x3
, __c
);
195 template <class, class _Compare
, class _RandomAccessIterator
,
196 __enable_if_t
<__use_branchless_sort
<_Compare
, _RandomAccessIterator
>::value
, int> = 0>
197 inline _LIBCPP_HIDE_FROM_ABI
void
198 __sort4_maybe_branchless(_RandomAccessIterator __x1
, _RandomAccessIterator __x2
, _RandomAccessIterator __x3
,
199 _RandomAccessIterator __x4
, _Compare __c
) {
200 std::__cond_swap
<_Compare
>(__x1
, __x3
, __c
);
201 std::__cond_swap
<_Compare
>(__x2
, __x4
, __c
);
202 std::__cond_swap
<_Compare
>(__x1
, __x2
, __c
);
203 std::__cond_swap
<_Compare
>(__x3
, __x4
, __c
);
204 std::__cond_swap
<_Compare
>(__x2
, __x3
, __c
);
207 template <class _AlgPolicy
, class _Compare
, class _RandomAccessIterator
,
208 __enable_if_t
<!__use_branchless_sort
<_Compare
, _RandomAccessIterator
>::value
, int> = 0>
209 inline _LIBCPP_HIDE_FROM_ABI
void
210 __sort4_maybe_branchless(_RandomAccessIterator __x1
, _RandomAccessIterator __x2
, _RandomAccessIterator __x3
,
211 _RandomAccessIterator __x4
, _Compare __c
) {
212 std::__sort4
<_AlgPolicy
, _Compare
>(__x1
, __x2
, __x3
, __x4
, __c
);
215 template <class _AlgPolicy
, class _Compare
, class _RandomAccessIterator
,
216 __enable_if_t
<__use_branchless_sort
<_Compare
, _RandomAccessIterator
>::value
, int> = 0>
217 inline _LIBCPP_HIDE_FROM_ABI
void
218 __sort5_maybe_branchless(
219 _RandomAccessIterator __x1
,
220 _RandomAccessIterator __x2
,
221 _RandomAccessIterator __x3
,
222 _RandomAccessIterator __x4
,
223 _RandomAccessIterator __x5
,
225 std::__cond_swap
<_Compare
>(__x1
, __x2
, __c
);
226 std::__cond_swap
<_Compare
>(__x4
, __x5
, __c
);
227 std::__partially_sorted_swap
<_Compare
>(__x3
, __x4
, __x5
, __c
);
228 std::__cond_swap
<_Compare
>(__x2
, __x5
, __c
);
229 std::__partially_sorted_swap
<_Compare
>(__x1
, __x3
, __x4
, __c
);
230 std::__partially_sorted_swap
<_Compare
>(__x2
, __x3
, __x4
, __c
);
233 template <class _AlgPolicy
, class _Compare
, class _RandomAccessIterator
,
234 __enable_if_t
<!__use_branchless_sort
<_Compare
, _RandomAccessIterator
>::value
, int> = 0>
235 inline _LIBCPP_HIDE_FROM_ABI
void
236 __sort5_maybe_branchless(_RandomAccessIterator __x1
, _RandomAccessIterator __x2
, _RandomAccessIterator __x3
,
237 _RandomAccessIterator __x4
, _RandomAccessIterator __x5
, _Compare __c
) {
238 std::__sort5
<_AlgPolicy
, _Compare
, _RandomAccessIterator
>(
239 std::move(__x1
), std::move(__x2
), std::move(__x3
), std::move(__x4
), std::move(__x5
), __c
);
243 template <class _AlgPolicy
, class _Compare
, class _BidirectionalIterator
>
244 _LIBCPP_HIDE_FROM_ABI
245 _LIBCPP_CONSTEXPR_SINCE_CXX14
void __selection_sort(_BidirectionalIterator __first
, _BidirectionalIterator __last
,
247 _BidirectionalIterator __lm1
= __last
;
248 for (--__lm1
; __first
!= __lm1
; ++__first
) {
249 _BidirectionalIterator __i
= std::__min_element
<_Compare
>(__first
, __last
, __comp
);
251 _IterOps
<_AlgPolicy
>::iter_swap(__first
, __i
);
255 // Sort the iterator range [__first, __last) using the comparator __comp using
256 // the insertion sort algorithm.
257 template <class _AlgPolicy
, class _Compare
, class _BidirectionalIterator
>
258 _LIBCPP_HIDE_FROM_ABI
259 void __insertion_sort(_BidirectionalIterator __first
, _BidirectionalIterator __last
, _Compare __comp
) {
260 using _Ops
= _IterOps
<_AlgPolicy
>;
262 typedef typename iterator_traits
<_BidirectionalIterator
>::value_type value_type
;
263 if (__first
== __last
)
265 _BidirectionalIterator __i
= __first
;
266 for (++__i
; __i
!= __last
; ++__i
) {
267 _BidirectionalIterator __j
= __i
;
269 if (__comp(*__i
, *__j
)) {
270 value_type
__t(_Ops::__iter_move(__i
));
271 _BidirectionalIterator __k
= __j
;
274 *__j
= _Ops::__iter_move(__k
);
276 } while (__j
!= __first
&& __comp(__t
, *--__k
));
277 *__j
= std::move(__t
);
282 // Sort the iterator range [__first, __last) using the comparator __comp using
283 // the insertion sort algorithm. Insertion sort has two loops, outer and inner.
284 // The implementation below has no bounds check (unguarded) for the inner loop.
285 // Assumes that there is an element in the position (__first - 1) and that each
286 // element in the input range is greater or equal to the element at __first - 1.
287 template <class _AlgPolicy
, class _Compare
, class _RandomAccessIterator
>
288 _LIBCPP_HIDE_FROM_ABI
void
289 __insertion_sort_unguarded(_RandomAccessIterator
const __first
, _RandomAccessIterator __last
, _Compare __comp
) {
290 using _Ops
= _IterOps
<_AlgPolicy
>;
291 typedef typename iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
292 typedef typename iterator_traits
<_RandomAccessIterator
>::value_type value_type
;
293 if (__first
== __last
)
295 const _RandomAccessIterator __leftmost
= __first
- difference_type(1); (void)__leftmost
; // can be unused when assertions are disabled
296 for (_RandomAccessIterator __i
= __first
+ difference_type(1); __i
!= __last
; ++__i
) {
297 _RandomAccessIterator __j
= __i
- difference_type(1);
298 if (__comp(*__i
, *__j
)) {
299 value_type
__t(_Ops::__iter_move(__i
));
300 _RandomAccessIterator __k
= __j
;
303 *__j
= _Ops::__iter_move(__k
);
305 _LIBCPP_ASSERT_UNCATEGORIZED(
307 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
308 } while (__comp(__t
, *--__k
)); // No need for bounds check due to the assumption stated above.
309 *__j
= std::move(__t
);
314 template <class _AlgPolicy
, class _Comp
, class _RandomAccessIterator
>
315 _LIBCPP_HIDE_FROM_ABI
bool __insertion_sort_incomplete(
316 _RandomAccessIterator __first
, _RandomAccessIterator __last
, _Comp __comp
) {
317 using _Ops
= _IterOps
<_AlgPolicy
>;
319 typedef typename iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
320 switch (__last
- __first
) {
325 if (__comp(*--__last
, *__first
))
326 _Ops::iter_swap(__first
, __last
);
329 std::__sort3_maybe_branchless
<_AlgPolicy
, _Comp
>(__first
, __first
+ difference_type(1), --__last
, __comp
);
332 std::__sort4_maybe_branchless
<_AlgPolicy
, _Comp
>(
333 __first
, __first
+ difference_type(1), __first
+ difference_type(2), --__last
, __comp
);
336 std::__sort5_maybe_branchless
<_AlgPolicy
, _Comp
>(
337 __first
, __first
+ difference_type(1), __first
+ difference_type(2), __first
+ difference_type(3),
341 typedef typename iterator_traits
<_RandomAccessIterator
>::value_type value_type
;
342 _RandomAccessIterator __j
= __first
+ difference_type(2);
343 std::__sort3_maybe_branchless
<_AlgPolicy
, _Comp
>(__first
, __first
+ difference_type(1), __j
, __comp
);
344 const unsigned __limit
= 8;
345 unsigned __count
= 0;
346 for (_RandomAccessIterator __i
= __j
+ difference_type(1); __i
!= __last
; ++__i
) {
347 if (__comp(*__i
, *__j
)) {
348 value_type
__t(_Ops::__iter_move(__i
));
349 _RandomAccessIterator __k
= __j
;
352 *__j
= _Ops::__iter_move(__k
);
354 } while (__j
!= __first
&& __comp(__t
, *--__k
));
355 *__j
= std::move(__t
);
356 if (++__count
== __limit
)
357 return ++__i
== __last
;
364 template <class _AlgPolicy
, class _RandomAccessIterator
>
365 inline _LIBCPP_HIDE_FROM_ABI
void __swap_bitmap_pos(
366 _RandomAccessIterator __first
, _RandomAccessIterator __last
, uint64_t& __left_bitset
, uint64_t& __right_bitset
) {
367 using _Ops
= _IterOps
<_AlgPolicy
>;
368 typedef typename
std::iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
369 // Swap one pair on each iteration as long as both bitsets have at least one
370 // element for swapping.
371 while (__left_bitset
!= 0 && __right_bitset
!= 0) {
372 difference_type __tz_left
= __libcpp_ctz(__left_bitset
);
373 __left_bitset
= __libcpp_blsr(__left_bitset
);
374 difference_type __tz_right
= __libcpp_ctz(__right_bitset
);
375 __right_bitset
= __libcpp_blsr(__right_bitset
);
376 _Ops::iter_swap(__first
+ __tz_left
, __last
- __tz_right
);
380 template <class _Compare
,
381 class _RandomAccessIterator
,
382 class _ValueType
= typename iterator_traits
<_RandomAccessIterator
>::value_type
>
383 inline _LIBCPP_HIDE_FROM_ABI
void
384 __populate_left_bitset(_RandomAccessIterator __first
, _Compare __comp
, _ValueType
& __pivot
, uint64_t& __left_bitset
) {
385 // Possible vectorization. With a proper "-march" flag, the following loop
386 // will be compiled into a set of SIMD instructions.
387 _RandomAccessIterator __iter
= __first
;
388 for (int __j
= 0; __j
< __detail::__block_size
;) {
389 bool __comp_result
= !__comp(*__iter
, __pivot
);
390 __left_bitset
|= (static_cast<uint64_t>(__comp_result
) << __j
);
396 template <class _Compare
,
397 class _RandomAccessIterator
,
398 class _ValueType
= typename iterator_traits
<_RandomAccessIterator
>::value_type
>
399 inline _LIBCPP_HIDE_FROM_ABI
void
400 __populate_right_bitset(_RandomAccessIterator __lm1
, _Compare __comp
, _ValueType
& __pivot
, uint64_t& __right_bitset
) {
401 // Possible vectorization. With a proper "-march" flag, the following loop
402 // will be compiled into a set of SIMD instructions.
403 _RandomAccessIterator __iter
= __lm1
;
404 for (int __j
= 0; __j
< __detail::__block_size
;) {
405 bool __comp_result
= __comp(*__iter
, __pivot
);
406 __right_bitset
|= (static_cast<uint64_t>(__comp_result
) << __j
);
412 template <class _AlgPolicy
,
414 class _RandomAccessIterator
,
415 class _ValueType
= typename iterator_traits
<_RandomAccessIterator
>::value_type
>
416 inline _LIBCPP_HIDE_FROM_ABI
void __bitset_partition_partial_blocks(
417 _RandomAccessIterator
& __first
,
418 _RandomAccessIterator
& __lm1
,
421 uint64_t& __left_bitset
,
422 uint64_t& __right_bitset
) {
423 typedef typename
std::iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
424 difference_type __remaining_len
= __lm1
- __first
+ 1;
425 difference_type __l_size
;
426 difference_type __r_size
;
427 if (__left_bitset
== 0 && __right_bitset
== 0) {
428 __l_size
= __remaining_len
/ 2;
429 __r_size
= __remaining_len
- __l_size
;
430 } else if (__left_bitset
== 0) {
431 // We know at least one side is a full block.
432 __l_size
= __remaining_len
- __detail::__block_size
;
433 __r_size
= __detail::__block_size
;
434 } else { // if (__right_bitset == 0)
435 __l_size
= __detail::__block_size
;
436 __r_size
= __remaining_len
- __detail::__block_size
;
438 // Record the comparison outcomes for the elements currently on the left side.
439 if (__left_bitset
== 0) {
440 _RandomAccessIterator __iter
= __first
;
441 for (int __j
= 0; __j
< __l_size
; __j
++) {
442 bool __comp_result
= !__comp(*__iter
, __pivot
);
443 __left_bitset
|= (static_cast<uint64_t>(__comp_result
) << __j
);
447 // Record the comparison outcomes for the elements currently on the right
449 if (__right_bitset
== 0) {
450 _RandomAccessIterator __iter
= __lm1
;
451 for (int __j
= 0; __j
< __r_size
; __j
++) {
452 bool __comp_result
= __comp(*__iter
, __pivot
);
453 __right_bitset
|= (static_cast<uint64_t>(__comp_result
) << __j
);
457 std::__swap_bitmap_pos
<_AlgPolicy
, _RandomAccessIterator
>(__first
, __lm1
, __left_bitset
, __right_bitset
);
458 __first
+= (__left_bitset
== 0) ? __l_size
: 0;
459 __lm1
-= (__right_bitset
== 0) ? __r_size
: 0;
462 template <class _AlgPolicy
, class _RandomAccessIterator
>
463 inline _LIBCPP_HIDE_FROM_ABI
void __swap_bitmap_pos_within(
464 _RandomAccessIterator
& __first
, _RandomAccessIterator
& __lm1
, uint64_t& __left_bitset
, uint64_t& __right_bitset
) {
465 using _Ops
= _IterOps
<_AlgPolicy
>;
466 typedef typename
std::iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
468 // Swap within the left side. Need to find set positions in the reverse
470 while (__left_bitset
!= 0) {
471 difference_type __tz_left
= __detail::__block_size
- 1 - __libcpp_clz(__left_bitset
);
472 __left_bitset
&= (static_cast<uint64_t>(1) << __tz_left
) - 1;
473 _RandomAccessIterator __it
= __first
+ __tz_left
;
475 _Ops::iter_swap(__it
, __lm1
);
479 __first
= __lm1
+ difference_type(1);
480 } else if (__right_bitset
) {
481 // Swap within the right side. Need to find set positions in the reverse
483 while (__right_bitset
!= 0) {
484 difference_type __tz_right
= __detail::__block_size
- 1 - __libcpp_clz(__right_bitset
);
485 __right_bitset
&= (static_cast<uint64_t>(1) << __tz_right
) - 1;
486 _RandomAccessIterator __it
= __lm1
- __tz_right
;
487 if (__it
!= __first
) {
488 _Ops::iter_swap(__it
, __first
);
495 // Partition [__first, __last) using the comparator __comp. *__first has the
496 // chosen pivot. Elements that are equivalent are kept to the left of the
497 // pivot. Returns the iterator for the pivot and a bool value which is true if
498 // the provided range is already sorted, false otherwise. We assume that the
499 // length of the range is at least three elements.
501 // __bitset_partition uses bitsets for storing outcomes of the comparisons
502 // between the pivot and other elements.
503 template <class _AlgPolicy
, class _RandomAccessIterator
, class _Compare
>
504 _LIBCPP_HIDE_FROM_ABI
std::pair
<_RandomAccessIterator
, bool>
505 __bitset_partition(_RandomAccessIterator __first
, _RandomAccessIterator __last
, _Compare __comp
) {
506 using _Ops
= _IterOps
<_AlgPolicy
>;
507 typedef typename
std::iterator_traits
<_RandomAccessIterator
>::value_type value_type
;
508 typedef typename
std::iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
509 _LIBCPP_ASSERT_UNCATEGORIZED(__last
- __first
>= difference_type(3), "");
510 const _RandomAccessIterator __begin
= __first
; // used for bounds checking, those are not moved around
511 const _RandomAccessIterator __end
= __last
; (void)__end
; //
513 value_type
__pivot(_Ops::__iter_move(__first
));
514 // Find the first element greater than the pivot.
515 if (__comp(__pivot
, *(__last
- difference_type(1)))) {
516 // Not guarded since we know the last element is greater than the pivot.
519 _LIBCPP_ASSERT_UNCATEGORIZED(
521 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
522 } while (!__comp(__pivot
, *__first
));
524 while (++__first
< __last
&& !__comp(__pivot
, *__first
)) {
527 // Find the last element less than or equal to the pivot.
528 if (__first
< __last
) {
529 // It will be always guarded because __introsort will do the median-of-three
530 // before calling this.
532 _LIBCPP_ASSERT_UNCATEGORIZED(
534 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
536 } while (__comp(__pivot
, *__last
));
538 // If the first element greater than the pivot is at or after the
539 // last element less than or equal to the pivot, then we have covered the
540 // entire range without swapping elements. This implies the range is already
542 bool __already_partitioned
= __first
>= __last
;
543 if (!__already_partitioned
) {
544 _Ops::iter_swap(__first
, __last
);
548 // In [__first, __last) __last is not inclusive. From now on, it uses last
549 // minus one to be inclusive on both sides.
550 _RandomAccessIterator __lm1
= __last
- difference_type(1);
551 uint64_t __left_bitset
= 0;
552 uint64_t __right_bitset
= 0;
554 // Reminder: length = __lm1 - __first + 1.
555 while (__lm1
- __first
>= 2 * __detail::__block_size
- 1) {
556 // Record the comparison outcomes for the elements currently on the left
558 if (__left_bitset
== 0)
559 std::__populate_left_bitset
<_Compare
>(__first
, __comp
, __pivot
, __left_bitset
);
560 // Record the comparison outcomes for the elements currently on the right
562 if (__right_bitset
== 0)
563 std::__populate_right_bitset
<_Compare
>(__lm1
, __comp
, __pivot
, __right_bitset
);
564 // Swap the elements recorded to be the candidates for swapping in the
566 std::__swap_bitmap_pos
<_AlgPolicy
, _RandomAccessIterator
>(__first
, __lm1
, __left_bitset
, __right_bitset
);
567 // Only advance the iterator if all the elements that need to be moved to
568 // other side were moved.
569 __first
+= (__left_bitset
== 0) ? difference_type(__detail::__block_size
) : difference_type(0);
570 __lm1
-= (__right_bitset
== 0) ? difference_type(__detail::__block_size
) : difference_type(0);
572 // Now, we have a less-than a block worth of elements on at least one of the
574 std::__bitset_partition_partial_blocks
<_AlgPolicy
, _Compare
>(
575 __first
, __lm1
, __comp
, __pivot
, __left_bitset
, __right_bitset
);
576 // At least one the bitsets would be empty. For the non-empty one, we need to
577 // properly partition the elements that appear within that bitset.
578 std::__swap_bitmap_pos_within
<_AlgPolicy
>(__first
, __lm1
, __left_bitset
, __right_bitset
);
580 // Move the pivot to its correct position.
581 _RandomAccessIterator __pivot_pos
= __first
- difference_type(1);
582 if (__begin
!= __pivot_pos
) {
583 *__begin
= _Ops::__iter_move(__pivot_pos
);
585 *__pivot_pos
= std::move(__pivot
);
586 return std::make_pair(__pivot_pos
, __already_partitioned
);
589 // Partition [__first, __last) using the comparator __comp. *__first has the
590 // chosen pivot. Elements that are equivalent are kept to the right of the
591 // pivot. Returns the iterator for the pivot and a bool value which is true if
592 // the provided range is already sorted, false otherwise. We assume that the
593 // length of the range is at least three elements.
594 template <class _AlgPolicy
, class _RandomAccessIterator
, class _Compare
>
595 _LIBCPP_HIDE_FROM_ABI
std::pair
<_RandomAccessIterator
, bool>
596 __partition_with_equals_on_right(_RandomAccessIterator __first
, _RandomAccessIterator __last
, _Compare __comp
) {
597 using _Ops
= _IterOps
<_AlgPolicy
>;
598 typedef typename iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
599 typedef typename
std::iterator_traits
<_RandomAccessIterator
>::value_type value_type
;
600 _LIBCPP_ASSERT_UNCATEGORIZED(__last
- __first
>= difference_type(3), "");
601 const _RandomAccessIterator __begin
= __first
; // used for bounds checking, those are not moved around
602 const _RandomAccessIterator __end
= __last
; (void)__end
; //
603 value_type
__pivot(_Ops::__iter_move(__first
));
604 // Find the first element greater or equal to the pivot. It will be always
605 // guarded because __introsort will do the median-of-three before calling
609 _LIBCPP_ASSERT_UNCATEGORIZED(
611 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
612 } while (__comp(*__first
, __pivot
));
614 // Find the last element less than the pivot.
615 if (__begin
== __first
- difference_type(1)) {
616 while (__first
< __last
&& !__comp(*--__last
, __pivot
))
621 _LIBCPP_ASSERT_UNCATEGORIZED(
623 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
625 } while (!__comp(*__last
, __pivot
));
628 // If the first element greater than or equal to the pivot is at or after the
629 // last element less than the pivot, then we have covered the entire range
630 // without swapping elements. This implies the range is already partitioned.
631 bool __already_partitioned
= __first
>= __last
;
632 // Go through the remaining elements. Swap pairs of elements (one to the
633 // right of the pivot and the other to left of the pivot) that are not on the
634 // correct side of the pivot.
635 while (__first
< __last
) {
636 _Ops::iter_swap(__first
, __last
);
639 _LIBCPP_ASSERT_UNCATEGORIZED(
641 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
642 } while (__comp(*__first
, __pivot
));
644 _LIBCPP_ASSERT_UNCATEGORIZED(
646 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
648 } while (!__comp(*__last
, __pivot
));
650 // Move the pivot to its correct position.
651 _RandomAccessIterator __pivot_pos
= __first
- difference_type(1);
652 if (__begin
!= __pivot_pos
) {
653 *__begin
= _Ops::__iter_move(__pivot_pos
);
655 *__pivot_pos
= std::move(__pivot
);
656 return std::make_pair(__pivot_pos
, __already_partitioned
);
659 // Similar to the above function. Elements equivalent to the pivot are put to
660 // the left of the pivot. Returns the iterator to the pivot element.
661 template <class _AlgPolicy
, class _RandomAccessIterator
, class _Compare
>
662 _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
663 __partition_with_equals_on_left(_RandomAccessIterator __first
, _RandomAccessIterator __last
, _Compare __comp
) {
664 using _Ops
= _IterOps
<_AlgPolicy
>;
665 typedef typename iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
666 typedef typename
std::iterator_traits
<_RandomAccessIterator
>::value_type value_type
;
667 // TODO(LLVM18): Make __begin const, see https://reviews.llvm.org/D147089#4349748
668 _RandomAccessIterator __begin
= __first
; // used for bounds checking, those are not moved around
669 const _RandomAccessIterator __end
= __last
; (void)__end
; //
670 value_type
__pivot(_Ops::__iter_move(__first
));
671 if (__comp(__pivot
, *(__last
- difference_type(1)))) {
675 _LIBCPP_ASSERT_UNCATEGORIZED(
677 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
678 } while (!__comp(__pivot
, *__first
));
680 while (++__first
< __last
&& !__comp(__pivot
, *__first
)) {
684 if (__first
< __last
) {
685 // It will be always guarded because __introsort will do the
686 // median-of-three before calling this.
688 _LIBCPP_ASSERT_UNCATEGORIZED(
690 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
692 } while (__comp(__pivot
, *__last
));
694 while (__first
< __last
) {
695 _Ops::iter_swap(__first
, __last
);
698 _LIBCPP_ASSERT_UNCATEGORIZED(
700 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
701 } while (!__comp(__pivot
, *__first
));
703 _LIBCPP_ASSERT_UNCATEGORIZED(
705 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
707 } while (__comp(__pivot
, *__last
));
709 _RandomAccessIterator __pivot_pos
= __first
- difference_type(1);
710 if (__begin
!= __pivot_pos
) {
711 *__begin
= _Ops::__iter_move(__pivot_pos
);
713 *__pivot_pos
= std::move(__pivot
);
717 // The main sorting function. Implements introsort combined with other ideas:
718 // - option of using block quick sort for partitioning,
719 // - guarded and unguarded insertion sort for small lengths,
720 // - Tuckey's ninther technique for computing the pivot,
721 // - check on whether partition was not required.
722 // The implementation is partly based on Orson Peters' pattern-defeating
723 // quicksort, published at: <https://github.com/orlp/pdqsort>.
724 template <class _AlgPolicy
, class _Compare
, class _RandomAccessIterator
, bool _UseBitSetPartition
>
725 void __introsort(_RandomAccessIterator __first
,
726 _RandomAccessIterator __last
,
728 typename iterator_traits
<_RandomAccessIterator
>::difference_type __depth
,
729 bool __leftmost
= true) {
730 using _Ops
= _IterOps
<_AlgPolicy
>;
731 typedef typename iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
732 using _Comp_ref
= __comp_ref_type
<_Compare
>;
733 // Upper bound for using insertion sort for sorting.
734 _LIBCPP_CONSTEXPR difference_type __limit
= 24;
735 // Lower bound for using Tuckey's ninther technique for median computation.
736 _LIBCPP_CONSTEXPR difference_type __ninther_threshold
= 128;
738 difference_type __len
= __last
- __first
;
744 if (__comp(*--__last
, *__first
))
745 _Ops::iter_swap(__first
, __last
);
748 std::__sort3_maybe_branchless
<_AlgPolicy
, _Compare
>(__first
, __first
+ difference_type(1), --__last
, __comp
);
751 std::__sort4_maybe_branchless
<_AlgPolicy
, _Compare
>(
752 __first
, __first
+ difference_type(1), __first
+ difference_type(2), --__last
, __comp
);
755 std::__sort5_maybe_branchless
<_AlgPolicy
, _Compare
>(
756 __first
, __first
+ difference_type(1), __first
+ difference_type(2), __first
+ difference_type(3),
760 // Use insertion sort if the length of the range is below the specified limit.
761 if (__len
< __limit
) {
763 std::__insertion_sort
<_AlgPolicy
, _Compare
>(__first
, __last
, __comp
);
765 std::__insertion_sort_unguarded
<_AlgPolicy
, _Compare
>(__first
, __last
, __comp
);
770 // Fallback to heap sort as Introsort suggests.
771 std::__partial_sort
<_AlgPolicy
, _Compare
>(__first
, __last
, __last
, __comp
);
776 difference_type __half_len
= __len
/ 2;
777 // Use Tuckey's ninther technique or median of 3 for pivot selection
778 // depending on the length of the range being sorted.
779 if (__len
> __ninther_threshold
) {
780 std::__sort3
<_AlgPolicy
, _Compare
>(__first
, __first
+ __half_len
, __last
- difference_type(1), __comp
);
781 std::__sort3
<_AlgPolicy
, _Compare
>(
782 __first
+ difference_type(1), __first
+ (__half_len
- 1), __last
- difference_type(2), __comp
);
783 std::__sort3
<_AlgPolicy
, _Compare
>(
784 __first
+ difference_type(2), __first
+ (__half_len
+ 1), __last
- difference_type(3), __comp
);
785 std::__sort3
<_AlgPolicy
, _Compare
>(
786 __first
+ (__half_len
- 1), __first
+ __half_len
, __first
+ (__half_len
+ 1), __comp
);
787 _Ops::iter_swap(__first
, __first
+ __half_len
);
789 std::__sort3
<_AlgPolicy
, _Compare
>(__first
+ __half_len
, __first
, __last
- difference_type(1), __comp
);
792 // The elements to the left of the current iterator range are already
793 // sorted. If the current iterator range to be sorted is not the
794 // leftmost part of the entire iterator range and the pivot is same as
795 // the highest element in the range to the left, then we know that all
796 // the elements in the range [first, pivot] would be equal to the pivot,
797 // assuming the equal elements are put on the left side when
798 // partitioned. This also means that we do not need to sort the left
799 // side of the partition.
800 if (!__leftmost
&& !__comp(*(__first
- difference_type(1)), *__first
)) {
801 __first
= std::__partition_with_equals_on_left
<_AlgPolicy
, _RandomAccessIterator
, _Comp_ref
>(
802 __first
, __last
, _Comp_ref(__comp
));
805 // Use bitset partition only if asked for.
808 ? std::__bitset_partition
<_AlgPolicy
, _RandomAccessIterator
, _Compare
>(__first
, __last
, __comp
)
809 : std::__partition_with_equals_on_right
<_AlgPolicy
, _RandomAccessIterator
, _Compare
>(__first
, __last
, __comp
);
810 _RandomAccessIterator __i
= __ret
.first
;
811 // [__first, __i) < *__i and *__i <= [__i+1, __last)
812 // If we were given a perfect partition, see if insertion sort is quick...
814 bool __fs
= std::__insertion_sort_incomplete
<_AlgPolicy
, _Compare
>(__first
, __i
, __comp
);
815 if (std::__insertion_sort_incomplete
<_AlgPolicy
, _Compare
>(__i
+ difference_type(1), __last
, __comp
)) {
827 // Sort the left partiton recursively and the right partition with tail recursion elimination.
828 std::__introsort
<_AlgPolicy
, _Compare
, _RandomAccessIterator
, _UseBitSetPartition
>(
829 __first
, __i
, __comp
, __depth
, __leftmost
);
835 template <typename _Number
>
836 inline _LIBCPP_HIDE_FROM_ABI _Number
__log2i(_Number __n
) {
839 if (sizeof(__n
) <= sizeof(unsigned))
840 return sizeof(unsigned) * CHAR_BIT
- 1 - __libcpp_clz(static_cast<unsigned>(__n
));
841 if (sizeof(__n
) <= sizeof(unsigned long))
842 return sizeof(unsigned long) * CHAR_BIT
- 1 - __libcpp_clz(static_cast<unsigned long>(__n
));
843 if (sizeof(__n
) <= sizeof(unsigned long long))
844 return sizeof(unsigned long long) * CHAR_BIT
- 1 - __libcpp_clz(static_cast<unsigned long long>(__n
));
854 template <class _Comp
, class _RandomAccessIterator
>
855 void __sort(_RandomAccessIterator
, _RandomAccessIterator
, _Comp
);
857 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<char>&, char*>(char*, char*, __less
<char>&);
858 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
859 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less
<wchar_t>&);
861 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<signed char>&, signed char*>(signed char*, signed char*, __less
<signed char>&);
862 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less
<unsigned char>&);
863 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<short>&, short*>(short*, short*, __less
<short>&);
864 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less
<unsigned short>&);
865 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<int>&, int*>(int*, int*, __less
<int>&);
866 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<unsigned>&, unsigned*>(unsigned*, unsigned*, __less
<unsigned>&);
867 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<long>&, long*>(long*, long*, __less
<long>&);
868 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less
<unsigned long>&);
869 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<long long>&, long long*>(long long*, long long*, __less
<long long>&);
870 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less
<unsigned long long>&);
871 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<float>&, float*>(float*, float*, __less
<float>&);
872 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<double>&, double*>(double*, double*, __less
<double>&);
873 extern template _LIBCPP_EXPORTED_FROM_ABI
void __sort
<__less
<long double>&, long double*>(long double*, long double*, __less
<long double>&);
875 template <class _AlgPolicy
, class _RandomAccessIterator
, class _Comp
>
876 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
877 __sort_dispatch(_RandomAccessIterator __first
, _RandomAccessIterator __last
, _Comp
& __comp
) {
878 typedef typename iterator_traits
<_RandomAccessIterator
>::difference_type difference_type
;
879 difference_type __depth_limit
= 2 * std::__log2i(__last
- __first
);
881 // Only use bitset partitioning for arithmetic types. We should also check
882 // that the default comparator is in use so that we are sure that there are no
883 // branches in the comparator.
884 std::__introsort
<_AlgPolicy
,
886 _RandomAccessIterator
,
887 __use_branchless_sort
<_Comp
, _RandomAccessIterator
>::value
>(
888 __first
, __last
, __comp
, __depth_limit
);
891 template <class _Type
, class... _Options
>
892 using __is_any_of
= _Or
<is_same
<_Type
, _Options
>...>;
894 template <class _Type
>
895 using __sort_is_specialized_in_library
= __is_any_of
<
898 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
915 template <class _AlgPolicy
, class _Type
, __enable_if_t
<__sort_is_specialized_in_library
<_Type
>::value
, int> = 0>
916 _LIBCPP_HIDE_FROM_ABI
void __sort_dispatch(_Type
* __first
, _Type
* __last
, __less
<>&) {
917 __less
<_Type
> __comp
;
918 std::__sort
<__less
<_Type
>&, _Type
*>(__first
, __last
, __comp
);
921 template <class _AlgPolicy
, class _Type
, __enable_if_t
<__sort_is_specialized_in_library
<_Type
>::value
, int> = 0>
922 _LIBCPP_HIDE_FROM_ABI
void __sort_dispatch(_Type
* __first
, _Type
* __last
, less
<_Type
>&) {
923 __less
<_Type
> __comp
;
924 std::__sort
<__less
<_Type
>&, _Type
*>(__first
, __last
, __comp
);
927 #if _LIBCPP_STD_VER >= 14
928 template <class _AlgPolicy
, class _Type
, __enable_if_t
<__sort_is_specialized_in_library
<_Type
>::value
, int> = 0>
929 _LIBCPP_HIDE_FROM_ABI
void __sort_dispatch(_Type
* __first
, _Type
* __last
, less
<>&) {
930 __less
<_Type
> __comp
;
931 std::__sort
<__less
<_Type
>&, _Type
*>(__first
, __last
, __comp
);
935 #if _LIBCPP_STD_VER >= 20
936 template <class _AlgPolicy
, class _Type
, __enable_if_t
<__sort_is_specialized_in_library
<_Type
>::value
, int> = 0>
937 _LIBCPP_HIDE_FROM_ABI
void __sort_dispatch(_Type
* __first
, _Type
* __last
, ranges::less
&) {
938 __less
<_Type
> __comp
;
939 std::__sort
<__less
<_Type
>&, _Type
*>(__first
, __last
, __comp
);
943 template <class _AlgPolicy
, class _RandomAccessIterator
, class _Comp
>
944 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
945 void __sort_impl(_RandomAccessIterator __first
, _RandomAccessIterator __last
, _Comp
& __comp
) {
946 std::__debug_randomize_range
<_AlgPolicy
>(__first
, __last
);
948 if (__libcpp_is_constant_evaluated()) {
949 std::__partial_sort
<_AlgPolicy
>(
950 std::__unwrap_iter(__first
), std::__unwrap_iter(__last
), std::__unwrap_iter(__last
), __comp
);
952 std::__sort_dispatch
<_AlgPolicy
>(std::__unwrap_iter(__first
), std::__unwrap_iter(__last
), __comp
);
954 std::__check_strict_weak_ordering_sorted(std::__unwrap_iter(__first
), std::__unwrap_iter(__last
), __comp
);
957 template <class _RandomAccessIterator
, class _Comp
>
958 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
959 void sort(_RandomAccessIterator __first
, _RandomAccessIterator __last
, _Comp __comp
) {
960 std::__sort_impl
<_ClassicAlgPolicy
>(std::move(__first
), std::move(__last
), __comp
);
963 template <class _RandomAccessIterator
>
964 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
965 void sort(_RandomAccessIterator __first
, _RandomAccessIterator __last
) {
966 std::sort(__first
, __last
, __less
<>());
969 _LIBCPP_END_NAMESPACE_STD
971 #endif // _LIBCPP___ALGORITHM_SORT_H