Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / include / __algorithm / sort.h
blob567c988ff0d3ced462f0a327441cde0d93e6898c
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
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>
19 #include <__assert>
20 #include <__bit/blsr.h>
21 #include <__bit/countl.h>
22 #include <__bit/countr.h>
23 #include <__config>
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>
35 #include <climits>
36 #include <cstdint>
38 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
39 # pragma GCC system_header
40 #endif
42 _LIBCPP_BEGIN_NAMESPACE_STD
44 // stable, 2-3 compares, 0-2 swaps
46 template <class _AlgPolicy, class _Compare, class _ForwardIterator>
47 _LIBCPP_HIDE_FROM_ABI
48 _LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z,
49 _Compare __c) {
50 using _Ops = _IterOps<_AlgPolicy>;
52 unsigned __r = 0;
53 if (!__c(*__y, *__x)) // if x <= y
55 if (!__c(*__z, *__y)) // if y <= z
56 return __r; // x <= y && y <= z
57 // x <= y && y > z
58 _Ops::iter_swap(__y, __z); // x <= z && y < z
59 __r = 1;
60 if (__c(*__y, *__x)) // if x > y
62 _Ops::iter_swap(__x, __y); // x < y && y <= z
63 __r = 2;
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
70 __r = 1;
71 return __r;
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
78 __r = 2;
80 return __r;
81 } // x <= y && y <= z
83 // stable, 3-6 compares, 0-5 swaps
85 template <class _AlgPolicy, class _Compare, class _ForwardIterator>
86 _LIBCPP_HIDE_FROM_ABI
87 void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4,
88 _Compare __c) {
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.
125 template <class _Tp>
126 struct __is_simple_comparator : false_type {};
127 template <>
128 struct __is_simple_comparator<__less<>&> : true_type {};
129 template <class _Tp>
130 struct __is_simple_comparator<less<_Tp>&> : true_type {};
131 template <class _Tp>
132 struct __is_simple_comparator<greater<_Tp>&> : true_type {};
133 #if _LIBCPP_STD_VER >= 20
134 template <>
135 struct __is_simple_comparator<ranges::less&> : true_type {};
136 template <>
137 struct __is_simple_comparator<ranges::greater&> : true_type {};
138 #endif
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>;
145 namespace __detail {
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;
160 *__x = __tmp;
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,
182 _Compare __c) {
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,
191 _Compare __c) {
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,
224 _Compare __c) {
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);
242 // Assumes size > 0
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,
246 _Compare __comp) {
247 _BidirectionalIterator __lm1 = __last;
248 for (--__lm1; __first != __lm1; ++__first) {
249 _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp);
250 if (__i != __first)
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)
264 return;
265 _BidirectionalIterator __i = __first;
266 for (++__i; __i != __last; ++__i) {
267 _BidirectionalIterator __j = __i;
268 --__j;
269 if (__comp(*__i, *__j)) {
270 value_type __t(_Ops::__iter_move(__i));
271 _BidirectionalIterator __k = __j;
272 __j = __i;
273 do {
274 *__j = _Ops::__iter_move(__k);
275 __j = __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)
294 return;
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;
301 __j = __i;
302 do {
303 *__j = _Ops::__iter_move(__k);
304 __j = __k;
305 _LIBCPP_ASSERT_UNCATEGORIZED(
306 __k != __leftmost,
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) {
321 case 0:
322 case 1:
323 return true;
324 case 2:
325 if (__comp(*--__last, *__first))
326 _Ops::iter_swap(__first, __last);
327 return true;
328 case 3:
329 std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), --__last, __comp);
330 return true;
331 case 4:
332 std::__sort4_maybe_branchless<_AlgPolicy, _Comp>(
333 __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
334 return true;
335 case 5:
336 std::__sort5_maybe_branchless<_AlgPolicy, _Comp>(
337 __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3),
338 --__last, __comp);
339 return true;
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;
350 __j = __i;
351 do {
352 *__j = _Ops::__iter_move(__k);
353 __j = __k;
354 } while (__j != __first && __comp(__t, *--__k));
355 *__j = std::move(__t);
356 if (++__count == __limit)
357 return ++__i == __last;
359 __j = __i;
361 return true;
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);
391 __j++;
392 ++__iter;
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);
407 __j++;
408 --__iter;
412 template <class _AlgPolicy,
413 class _Compare,
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,
419 _Compare __comp,
420 _ValueType& __pivot,
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);
444 ++__iter;
447 // Record the comparison outcomes for the elements currently on the right
448 // side.
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);
454 --__iter;
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;
467 if (__left_bitset) {
468 // Swap within the left side. Need to find set positions in the reverse
469 // order.
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;
474 if (__it != __lm1) {
475 _Ops::iter_swap(__it, __lm1);
477 --__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
482 // order.
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);
490 ++__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.
517 do {
518 ++__first;
519 _LIBCPP_ASSERT_UNCATEGORIZED(
520 __first != __end,
521 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
522 } while (!__comp(__pivot, *__first));
523 } else {
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.
531 do {
532 _LIBCPP_ASSERT_UNCATEGORIZED(
533 __last != __begin,
534 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
535 --__last;
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
541 // partitioned.
542 bool __already_partitioned = __first >= __last;
543 if (!__already_partitioned) {
544 _Ops::iter_swap(__first, __last);
545 ++__first;
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
557 // side.
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
561 // side.
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
565 // bitsets.
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
573 // sides.
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
606 // this.
607 do {
608 ++__first;
609 _LIBCPP_ASSERT_UNCATEGORIZED(
610 __first != __end,
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))
618 } else {
619 // Guarded.
620 do {
621 _LIBCPP_ASSERT_UNCATEGORIZED(
622 __last != __begin,
623 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
624 --__last;
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);
637 do {
638 ++__first;
639 _LIBCPP_ASSERT_UNCATEGORIZED(
640 __first != __end,
641 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
642 } while (__comp(*__first, __pivot));
643 do {
644 _LIBCPP_ASSERT_UNCATEGORIZED(
645 __last != __begin,
646 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
647 --__last;
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)))) {
672 // Guarded.
673 do {
674 ++__first;
675 _LIBCPP_ASSERT_UNCATEGORIZED(
676 __first != __end,
677 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
678 } while (!__comp(__pivot, *__first));
679 } else {
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.
687 do {
688 _LIBCPP_ASSERT_UNCATEGORIZED(
689 __last != __begin,
690 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
691 --__last;
692 } while (__comp(__pivot, *__last));
694 while (__first < __last) {
695 _Ops::iter_swap(__first, __last);
696 do {
697 ++__first;
698 _LIBCPP_ASSERT_UNCATEGORIZED(
699 __first != __end,
700 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
701 } while (!__comp(__pivot, *__first));
702 do {
703 _LIBCPP_ASSERT_UNCATEGORIZED(
704 __last != __begin,
705 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
706 --__last;
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);
714 return __first;
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,
727 _Compare __comp,
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;
737 while (true) {
738 difference_type __len = __last - __first;
739 switch (__len) {
740 case 0:
741 case 1:
742 return;
743 case 2:
744 if (__comp(*--__last, *__first))
745 _Ops::iter_swap(__first, __last);
746 return;
747 case 3:
748 std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp);
749 return;
750 case 4:
751 std::__sort4_maybe_branchless<_AlgPolicy, _Compare>(
752 __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
753 return;
754 case 5:
755 std::__sort5_maybe_branchless<_AlgPolicy, _Compare>(
756 __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3),
757 --__last, __comp);
758 return;
760 // Use insertion sort if the length of the range is below the specified limit.
761 if (__len < __limit) {
762 if (__leftmost) {
763 std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
764 } else {
765 std::__insertion_sort_unguarded<_AlgPolicy, _Compare>(__first, __last, __comp);
767 return;
769 if (__depth == 0) {
770 // Fallback to heap sort as Introsort suggests.
771 std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp);
772 return;
774 --__depth;
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);
788 } else {
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));
803 continue;
805 // Use bitset partition only if asked for.
806 auto __ret =
807 _UseBitSetPartition
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...
813 if (__ret.second) {
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)) {
816 if (__fs)
817 return;
818 __last = __i;
819 continue;
820 } else {
821 if (__fs) {
822 __first = ++__i;
823 continue;
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);
830 __leftmost = false;
831 __first = ++__i;
835 template <typename _Number>
836 inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) {
837 if (__n == 0)
838 return 0;
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));
846 _Number __log2 = 0;
847 while (__n > 1) {
848 __log2++;
849 __n >>= 1;
851 return __log2;
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>&);
860 #endif
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,
885 _Comp&,
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<
896 _Type,
897 char,
898 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
899 wchar_t,
900 #endif
901 signed char,
902 unsigned char,
903 short,
904 unsigned short,
905 int,
906 unsigned int,
907 long,
908 unsigned long,
909 long long,
910 unsigned long long,
911 float,
912 double,
913 long double>;
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);
933 #endif
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);
941 #endif
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);
951 } else {
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