File indexing completed on 2026-05-03 08:13:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _LIBCPP___ALGORITHM_SORT_H
0010 #define _LIBCPP___ALGORITHM_SORT_H
0011
0012 #include <__algorithm/comp.h>
0013 #include <__algorithm/comp_ref_type.h>
0014 #include <__algorithm/iter_swap.h>
0015 #include <__algorithm/iterator_operations.h>
0016 #include <__algorithm/min_element.h>
0017 #include <__algorithm/partial_sort.h>
0018 #include <__algorithm/unwrap_iter.h>
0019 #include <__assert>
0020 #include <__bit/blsr.h>
0021 #include <__bit/countl.h>
0022 #include <__bit/countr.h>
0023 #include <__config>
0024 #include <__debug_utils/randomize_range.h>
0025 #include <__debug_utils/strict_weak_ordering_check.h>
0026 #include <__functional/operations.h>
0027 #include <__functional/ranges_operations.h>
0028 #include <__iterator/iterator_traits.h>
0029 #include <__type_traits/conditional.h>
0030 #include <__type_traits/desugars_to.h>
0031 #include <__type_traits/disjunction.h>
0032 #include <__type_traits/enable_if.h>
0033 #include <__type_traits/is_arithmetic.h>
0034 #include <__type_traits/is_constant_evaluated.h>
0035 #include <__type_traits/is_same.h>
0036 #include <__type_traits/is_trivially_copyable.h>
0037 #include <__type_traits/remove_cvref.h>
0038 #include <__utility/move.h>
0039 #include <__utility/pair.h>
0040 #include <climits>
0041 #include <cstdint>
0042
0043 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0044 # pragma GCC system_header
0045 #endif
0046
0047 _LIBCPP_PUSH_MACROS
0048 #include <__undef_macros>
0049
0050 _LIBCPP_BEGIN_NAMESPACE_STD
0051
0052 template <class _Compare, class _Iter, class _Tp = typename iterator_traits<_Iter>::value_type>
0053 inline const bool __use_branchless_sort =
0054 __libcpp_is_contiguous_iterator<_Iter>::value && __is_cheap_to_copy<_Tp> && is_arithmetic<_Tp>::value &&
0055 (__desugars_to_v<__less_tag, __remove_cvref_t<_Compare>, _Tp, _Tp> ||
0056 __desugars_to_v<__greater_tag, __remove_cvref_t<_Compare>, _Tp, _Tp>);
0057
0058 namespace __detail {
0059
0060
0061 enum { __block_size = sizeof(uint64_t) * 8 };
0062
0063 }
0064
0065
0066 template <class _Compare, class _RandomAccessIterator>
0067 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0068 __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) {
0069
0070 using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
0071 bool __r = __c(*__x, *__y);
0072 value_type __tmp = __r ? *__x : *__y;
0073 *__y = __r ? *__y : *__x;
0074 *__x = __tmp;
0075 return !__r;
0076 }
0077
0078
0079
0080 template <class _Compare, class _RandomAccessIterator>
0081 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0082 __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _RandomAccessIterator __z, _Compare __c) {
0083
0084 using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
0085 bool __r1 = __c(*__z, *__x);
0086 value_type __tmp = __r1 ? *__z : *__x;
0087 *__z = __r1 ? *__x : *__z;
0088 bool __r2 = __c(__tmp, *__y);
0089 *__x = __r2 ? *__x : *__y;
0090 *__y = __r2 ? *__y : __tmp;
0091 return !__r1 || !__r2;
0092 }
0093
0094
0095
0096 template <class,
0097 class _Compare,
0098 class _RandomAccessIterator,
0099 __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
0100 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0101 __sort3(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _Compare __c) {
0102 bool __swapped1 = std::__cond_swap<_Compare>(__x2, __x3, __c);
0103 bool __swapped2 = std::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c);
0104 return __swapped1 || __swapped2;
0105 }
0106
0107 template <class _AlgPolicy,
0108 class _Compare,
0109 class _RandomAccessIterator,
0110 __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
0111 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0112 __sort3(_RandomAccessIterator __x, _RandomAccessIterator __y, _RandomAccessIterator __z, _Compare __c) {
0113 using _Ops = _IterOps<_AlgPolicy>;
0114
0115 if (!__c(*__y, *__x))
0116 {
0117 if (!__c(*__z, *__y))
0118 return false;
0119
0120 _Ops::iter_swap(__y, __z);
0121 if (__c(*__y, *__x))
0122 _Ops::iter_swap(__x, __y);
0123 return true;
0124 }
0125 if (__c(*__z, *__y))
0126 {
0127 _Ops::iter_swap(__x, __z);
0128 return true;
0129 }
0130 _Ops::iter_swap(__x, __y);
0131
0132 if (__c(*__z, *__y))
0133 _Ops::iter_swap(__y, __z);
0134 return true;
0135 }
0136
0137
0138
0139 template <class,
0140 class _Compare,
0141 class _RandomAccessIterator,
0142 __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
0143 inline _LIBCPP_HIDE_FROM_ABI void
0144 __sort4(_RandomAccessIterator __x1,
0145 _RandomAccessIterator __x2,
0146 _RandomAccessIterator __x3,
0147 _RandomAccessIterator __x4,
0148 _Compare __c) {
0149 std::__cond_swap<_Compare>(__x1, __x3, __c);
0150 std::__cond_swap<_Compare>(__x2, __x4, __c);
0151 std::__cond_swap<_Compare>(__x1, __x2, __c);
0152 std::__cond_swap<_Compare>(__x3, __x4, __c);
0153 std::__cond_swap<_Compare>(__x2, __x3, __c);
0154 }
0155
0156 template <class _AlgPolicy,
0157 class _Compare,
0158 class _RandomAccessIterator,
0159 __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
0160 inline _LIBCPP_HIDE_FROM_ABI void
0161 __sort4(_RandomAccessIterator __x1,
0162 _RandomAccessIterator __x2,
0163 _RandomAccessIterator __x3,
0164 _RandomAccessIterator __x4,
0165 _Compare __c) {
0166 using _Ops = _IterOps<_AlgPolicy>;
0167 std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c);
0168 if (__c(*__x4, *__x3)) {
0169 _Ops::iter_swap(__x3, __x4);
0170 if (__c(*__x3, *__x2)) {
0171 _Ops::iter_swap(__x2, __x3);
0172 if (__c(*__x2, *__x1)) {
0173 _Ops::iter_swap(__x1, __x2);
0174 }
0175 }
0176 }
0177 }
0178
0179
0180
0181 template <class _AlgPolicy,
0182 class _Compare,
0183 class _RandomAccessIterator,
0184 __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
0185 inline _LIBCPP_HIDE_FROM_ABI void
0186 __sort5(_RandomAccessIterator __x1,
0187 _RandomAccessIterator __x2,
0188 _RandomAccessIterator __x3,
0189 _RandomAccessIterator __x4,
0190 _RandomAccessIterator __x5,
0191 _Compare __c) {
0192 std::__cond_swap<_Compare>(__x1, __x2, __c);
0193 std::__cond_swap<_Compare>(__x4, __x5, __c);
0194 std::__partially_sorted_swap<_Compare>(__x3, __x4, __x5, __c);
0195 std::__cond_swap<_Compare>(__x2, __x5, __c);
0196 std::__partially_sorted_swap<_Compare>(__x1, __x3, __x4, __c);
0197 std::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c);
0198 }
0199
0200 template <class _AlgPolicy,
0201 class _Compare,
0202 class _RandomAccessIterator,
0203 __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
0204 inline _LIBCPP_HIDE_FROM_ABI void
0205 __sort5(_RandomAccessIterator __x1,
0206 _RandomAccessIterator __x2,
0207 _RandomAccessIterator __x3,
0208 _RandomAccessIterator __x4,
0209 _RandomAccessIterator __x5,
0210 _Compare __comp) {
0211 using _Ops = _IterOps<_AlgPolicy>;
0212
0213 std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __comp);
0214 if (__comp(*__x5, *__x4)) {
0215 _Ops::iter_swap(__x4, __x5);
0216 if (__comp(*__x4, *__x3)) {
0217 _Ops::iter_swap(__x3, __x4);
0218 if (__comp(*__x3, *__x2)) {
0219 _Ops::iter_swap(__x2, __x3);
0220 if (__comp(*__x2, *__x1)) {
0221 _Ops::iter_swap(__x1, __x2);
0222 }
0223 }
0224 }
0225 }
0226 }
0227
0228
0229 template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
0230 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
0231 __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
0232 _BidirectionalIterator __lm1 = __last;
0233 for (--__lm1; __first != __lm1; ++__first) {
0234 _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp);
0235 if (__i != __first)
0236 _IterOps<_AlgPolicy>::iter_swap(__first, __i);
0237 }
0238 }
0239
0240
0241
0242 template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
0243 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
0244 __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
0245 using _Ops = _IterOps<_AlgPolicy>;
0246
0247 typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
0248 if (__first == __last)
0249 return;
0250 _BidirectionalIterator __i = __first;
0251 for (++__i; __i != __last; ++__i) {
0252 _BidirectionalIterator __j = __i;
0253 --__j;
0254 if (__comp(*__i, *__j)) {
0255 value_type __t(_Ops::__iter_move(__i));
0256 _BidirectionalIterator __k = __j;
0257 __j = __i;
0258 do {
0259 *__j = _Ops::__iter_move(__k);
0260 __j = __k;
0261 } while (__j != __first && __comp(__t, *--__k));
0262 *__j = std::move(__t);
0263 }
0264 }
0265 }
0266
0267
0268
0269
0270
0271
0272 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
0273 _LIBCPP_HIDE_FROM_ABI void
0274 __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIterator __last, _Compare __comp) {
0275 using _Ops = _IterOps<_AlgPolicy>;
0276 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0277 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
0278 if (__first == __last)
0279 return;
0280 const _RandomAccessIterator __leftmost = __first - difference_type(1);
0281 (void)__leftmost;
0282 for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) {
0283 _RandomAccessIterator __j = __i - difference_type(1);
0284 if (__comp(*__i, *__j)) {
0285 value_type __t(_Ops::__iter_move(__i));
0286 _RandomAccessIterator __k = __j;
0287 __j = __i;
0288 do {
0289 *__j = _Ops::__iter_move(__k);
0290 __j = __k;
0291 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0292 __k != __leftmost,
0293 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0294 } while (__comp(__t, *--__k));
0295 *__j = std::move(__t);
0296 }
0297 }
0298 }
0299
0300 template <class _AlgPolicy, class _Comp, class _RandomAccessIterator>
0301 _LIBCPP_HIDE_FROM_ABI bool
0302 __insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
0303 using _Ops = _IterOps<_AlgPolicy>;
0304
0305 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0306 switch (__last - __first) {
0307 case 0:
0308 case 1:
0309 return true;
0310 case 2:
0311 if (__comp(*--__last, *__first))
0312 _Ops::iter_swap(__first, __last);
0313 return true;
0314 case 3:
0315 std::__sort3<_AlgPolicy, _Comp>(__first, __first + difference_type(1), --__last, __comp);
0316 return true;
0317 case 4:
0318 std::__sort4<_AlgPolicy, _Comp>(
0319 __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
0320 return true;
0321 case 5:
0322 std::__sort5<_AlgPolicy, _Comp>(
0323 __first,
0324 __first + difference_type(1),
0325 __first + difference_type(2),
0326 __first + difference_type(3),
0327 --__last,
0328 __comp);
0329 return true;
0330 }
0331 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
0332 _RandomAccessIterator __j = __first + difference_type(2);
0333 std::__sort3<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp);
0334 const unsigned __limit = 8;
0335 unsigned __count = 0;
0336 for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
0337 if (__comp(*__i, *__j)) {
0338 value_type __t(_Ops::__iter_move(__i));
0339 _RandomAccessIterator __k = __j;
0340 __j = __i;
0341 do {
0342 *__j = _Ops::__iter_move(__k);
0343 __j = __k;
0344 } while (__j != __first && __comp(__t, *--__k));
0345 *__j = std::move(__t);
0346 if (++__count == __limit)
0347 return ++__i == __last;
0348 }
0349 __j = __i;
0350 }
0351 return true;
0352 }
0353
0354 template <class _AlgPolicy, class _RandomAccessIterator>
0355 inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos(
0356 _RandomAccessIterator __first, _RandomAccessIterator __last, uint64_t& __left_bitset, uint64_t& __right_bitset) {
0357 using _Ops = _IterOps<_AlgPolicy>;
0358 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0359
0360
0361 while (__left_bitset != 0 && __right_bitset != 0) {
0362 difference_type __tz_left = __libcpp_ctz(__left_bitset);
0363 __left_bitset = __libcpp_blsr(__left_bitset);
0364 difference_type __tz_right = __libcpp_ctz(__right_bitset);
0365 __right_bitset = __libcpp_blsr(__right_bitset);
0366 _Ops::iter_swap(__first + __tz_left, __last - __tz_right);
0367 }
0368 }
0369
0370 template <class _Compare,
0371 class _RandomAccessIterator,
0372 class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
0373 inline _LIBCPP_HIDE_FROM_ABI void
0374 __populate_left_bitset(_RandomAccessIterator __first, _Compare __comp, _ValueType& __pivot, uint64_t& __left_bitset) {
0375
0376
0377 _RandomAccessIterator __iter = __first;
0378 for (int __j = 0; __j < __detail::__block_size;) {
0379 bool __comp_result = !__comp(*__iter, __pivot);
0380 __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
0381 __j++;
0382 ++__iter;
0383 }
0384 }
0385
0386 template <class _Compare,
0387 class _RandomAccessIterator,
0388 class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
0389 inline _LIBCPP_HIDE_FROM_ABI void
0390 __populate_right_bitset(_RandomAccessIterator __lm1, _Compare __comp, _ValueType& __pivot, uint64_t& __right_bitset) {
0391
0392
0393 _RandomAccessIterator __iter = __lm1;
0394 for (int __j = 0; __j < __detail::__block_size;) {
0395 bool __comp_result = __comp(*__iter, __pivot);
0396 __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
0397 __j++;
0398 --__iter;
0399 }
0400 }
0401
0402 template <class _AlgPolicy,
0403 class _Compare,
0404 class _RandomAccessIterator,
0405 class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
0406 inline _LIBCPP_HIDE_FROM_ABI void __bitset_partition_partial_blocks(
0407 _RandomAccessIterator& __first,
0408 _RandomAccessIterator& __lm1,
0409 _Compare __comp,
0410 _ValueType& __pivot,
0411 uint64_t& __left_bitset,
0412 uint64_t& __right_bitset) {
0413 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0414 difference_type __remaining_len = __lm1 - __first + 1;
0415 difference_type __l_size;
0416 difference_type __r_size;
0417 if (__left_bitset == 0 && __right_bitset == 0) {
0418 __l_size = __remaining_len / 2;
0419 __r_size = __remaining_len - __l_size;
0420 } else if (__left_bitset == 0) {
0421
0422 __l_size = __remaining_len - __detail::__block_size;
0423 __r_size = __detail::__block_size;
0424 } else {
0425 __l_size = __detail::__block_size;
0426 __r_size = __remaining_len - __detail::__block_size;
0427 }
0428
0429 if (__left_bitset == 0) {
0430 _RandomAccessIterator __iter = __first;
0431 for (int __j = 0; __j < __l_size; __j++) {
0432 bool __comp_result = !__comp(*__iter, __pivot);
0433 __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
0434 ++__iter;
0435 }
0436 }
0437
0438
0439 if (__right_bitset == 0) {
0440 _RandomAccessIterator __iter = __lm1;
0441 for (int __j = 0; __j < __r_size; __j++) {
0442 bool __comp_result = __comp(*__iter, __pivot);
0443 __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
0444 --__iter;
0445 }
0446 }
0447 std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset);
0448 __first += (__left_bitset == 0) ? __l_size : 0;
0449 __lm1 -= (__right_bitset == 0) ? __r_size : 0;
0450 }
0451
0452 template <class _AlgPolicy, class _RandomAccessIterator>
0453 inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos_within(
0454 _RandomAccessIterator& __first, _RandomAccessIterator& __lm1, uint64_t& __left_bitset, uint64_t& __right_bitset) {
0455 using _Ops = _IterOps<_AlgPolicy>;
0456 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0457 if (__left_bitset) {
0458
0459
0460 while (__left_bitset != 0) {
0461 difference_type __tz_left = __detail::__block_size - 1 - __libcpp_clz(__left_bitset);
0462 __left_bitset &= (static_cast<uint64_t>(1) << __tz_left) - 1;
0463 _RandomAccessIterator __it = __first + __tz_left;
0464 if (__it != __lm1) {
0465 _Ops::iter_swap(__it, __lm1);
0466 }
0467 --__lm1;
0468 }
0469 __first = __lm1 + difference_type(1);
0470 } else if (__right_bitset) {
0471
0472
0473 while (__right_bitset != 0) {
0474 difference_type __tz_right = __detail::__block_size - 1 - __libcpp_clz(__right_bitset);
0475 __right_bitset &= (static_cast<uint64_t>(1) << __tz_right) - 1;
0476 _RandomAccessIterator __it = __lm1 - __tz_right;
0477 if (__it != __first) {
0478 _Ops::iter_swap(__it, __first);
0479 }
0480 ++__first;
0481 }
0482 }
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
0494 _LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool>
0495 __bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
0496 using _Ops = _IterOps<_AlgPolicy>;
0497 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
0498 typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0499 _LIBCPP_ASSERT_INTERNAL(__last - __first >= difference_type(3), "");
0500 const _RandomAccessIterator __begin = __first;
0501 const _RandomAccessIterator __end = __last;
0502 (void)__end;
0503
0504 value_type __pivot(_Ops::__iter_move(__first));
0505
0506 if (__comp(__pivot, *(__last - difference_type(1)))) {
0507
0508 do {
0509 ++__first;
0510 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0511 __first != __end,
0512 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0513 } while (!__comp(__pivot, *__first));
0514 } else {
0515 while (++__first < __last && !__comp(__pivot, *__first)) {
0516 }
0517 }
0518
0519 if (__first < __last) {
0520
0521
0522 do {
0523 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0524 __last != __begin,
0525 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0526 --__last;
0527 } while (__comp(__pivot, *__last));
0528 }
0529
0530
0531
0532
0533 bool __already_partitioned = __first >= __last;
0534 if (!__already_partitioned) {
0535 _Ops::iter_swap(__first, __last);
0536 ++__first;
0537 }
0538
0539
0540
0541 _RandomAccessIterator __lm1 = __last - difference_type(1);
0542 uint64_t __left_bitset = 0;
0543 uint64_t __right_bitset = 0;
0544
0545
0546 while (__lm1 - __first >= 2 * __detail::__block_size - 1) {
0547
0548
0549 if (__left_bitset == 0)
0550 std::__populate_left_bitset<_Compare>(__first, __comp, __pivot, __left_bitset);
0551
0552
0553 if (__right_bitset == 0)
0554 std::__populate_right_bitset<_Compare>(__lm1, __comp, __pivot, __right_bitset);
0555
0556
0557 std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset);
0558
0559
0560 __first += (__left_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0);
0561 __lm1 -= (__right_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0);
0562 }
0563
0564
0565 std::__bitset_partition_partial_blocks<_AlgPolicy, _Compare>(
0566 __first, __lm1, __comp, __pivot, __left_bitset, __right_bitset);
0567
0568
0569 std::__swap_bitmap_pos_within<_AlgPolicy>(__first, __lm1, __left_bitset, __right_bitset);
0570
0571
0572 _RandomAccessIterator __pivot_pos = __first - difference_type(1);
0573 if (__begin != __pivot_pos) {
0574 *__begin = _Ops::__iter_move(__pivot_pos);
0575 }
0576 *__pivot_pos = std::move(__pivot);
0577 return std::make_pair(__pivot_pos, __already_partitioned);
0578 }
0579
0580
0581
0582
0583
0584
0585 template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
0586 _LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool>
0587 __partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
0588 using _Ops = _IterOps<_AlgPolicy>;
0589 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0590 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
0591 _LIBCPP_ASSERT_INTERNAL(__last - __first >= difference_type(3), "");
0592 const _RandomAccessIterator __begin = __first;
0593 const _RandomAccessIterator __end = __last;
0594 (void)__end;
0595 value_type __pivot(_Ops::__iter_move(__first));
0596
0597
0598
0599 do {
0600 ++__first;
0601 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0602 __first != __end,
0603 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0604 } while (__comp(*__first, __pivot));
0605
0606
0607 if (__begin == __first - difference_type(1)) {
0608 while (__first < __last && !__comp(*--__last, __pivot))
0609 ;
0610 } else {
0611
0612 do {
0613 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0614 __last != __begin,
0615 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0616 --__last;
0617 } while (!__comp(*__last, __pivot));
0618 }
0619
0620
0621
0622
0623 bool __already_partitioned = __first >= __last;
0624
0625
0626
0627 while (__first < __last) {
0628 _Ops::iter_swap(__first, __last);
0629 do {
0630 ++__first;
0631 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0632 __first != __end,
0633 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0634 } while (__comp(*__first, __pivot));
0635 do {
0636 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0637 __last != __begin,
0638 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0639 --__last;
0640 } while (!__comp(*__last, __pivot));
0641 }
0642
0643 _RandomAccessIterator __pivot_pos = __first - difference_type(1);
0644 if (__begin != __pivot_pos) {
0645 *__begin = _Ops::__iter_move(__pivot_pos);
0646 }
0647 *__pivot_pos = std::move(__pivot);
0648 return std::make_pair(__pivot_pos, __already_partitioned);
0649 }
0650
0651
0652
0653 template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
0654 _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
0655 __partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
0656 using _Ops = _IterOps<_AlgPolicy>;
0657 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0658 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
0659 const _RandomAccessIterator __begin = __first;
0660 const _RandomAccessIterator __end = __last;
0661 (void)__end;
0662 value_type __pivot(_Ops::__iter_move(__first));
0663 if (__comp(__pivot, *(__last - difference_type(1)))) {
0664
0665 do {
0666 ++__first;
0667 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0668 __first != __end,
0669 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0670 } while (!__comp(__pivot, *__first));
0671 } else {
0672 while (++__first < __last && !__comp(__pivot, *__first)) {
0673 }
0674 }
0675
0676 if (__first < __last) {
0677
0678
0679 do {
0680 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0681 __last != __begin,
0682 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0683 --__last;
0684 } while (__comp(__pivot, *__last));
0685 }
0686 while (__first < __last) {
0687 _Ops::iter_swap(__first, __last);
0688 do {
0689 ++__first;
0690 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0691 __first != __end,
0692 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0693 } while (!__comp(__pivot, *__first));
0694 do {
0695 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0696 __last != __begin,
0697 "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
0698 --__last;
0699 } while (__comp(__pivot, *__last));
0700 }
0701 _RandomAccessIterator __pivot_pos = __first - difference_type(1);
0702 if (__begin != __pivot_pos) {
0703 *__begin = _Ops::__iter_move(__pivot_pos);
0704 }
0705 *__pivot_pos = std::move(__pivot);
0706 return __first;
0707 }
0708
0709
0710
0711
0712
0713
0714
0715
0716 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, bool _UseBitSetPartition>
0717 void __introsort(_RandomAccessIterator __first,
0718 _RandomAccessIterator __last,
0719 _Compare __comp,
0720 typename iterator_traits<_RandomAccessIterator>::difference_type __depth,
0721 bool __leftmost = true) {
0722 using _Ops = _IterOps<_AlgPolicy>;
0723 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0724 using _Comp_ref = __comp_ref_type<_Compare>;
0725
0726 _LIBCPP_CONSTEXPR difference_type __limit = 24;
0727
0728 _LIBCPP_CONSTEXPR difference_type __ninther_threshold = 128;
0729 while (true) {
0730 difference_type __len = __last - __first;
0731 switch (__len) {
0732 case 0:
0733 case 1:
0734 return;
0735 case 2:
0736 if (__comp(*--__last, *__first))
0737 _Ops::iter_swap(__first, __last);
0738 return;
0739 case 3:
0740 std::__sort3<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp);
0741 return;
0742 case 4:
0743 std::__sort4<_AlgPolicy, _Compare>(
0744 __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
0745 return;
0746 case 5:
0747 std::__sort5<_AlgPolicy, _Compare>(
0748 __first,
0749 __first + difference_type(1),
0750 __first + difference_type(2),
0751 __first + difference_type(3),
0752 --__last,
0753 __comp);
0754 return;
0755 }
0756
0757 if (__len < __limit) {
0758 if (__leftmost) {
0759 std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
0760 } else {
0761 std::__insertion_sort_unguarded<_AlgPolicy, _Compare>(__first, __last, __comp);
0762 }
0763 return;
0764 }
0765 if (__depth == 0) {
0766
0767 std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp);
0768 return;
0769 }
0770 --__depth;
0771 {
0772 difference_type __half_len = __len / 2;
0773
0774
0775 if (__len > __ninther_threshold) {
0776 std::__sort3<_AlgPolicy, _Compare>(__first, __first + __half_len, __last - difference_type(1), __comp);
0777 std::__sort3<_AlgPolicy, _Compare>(
0778 __first + difference_type(1), __first + (__half_len - 1), __last - difference_type(2), __comp);
0779 std::__sort3<_AlgPolicy, _Compare>(
0780 __first + difference_type(2), __first + (__half_len + 1), __last - difference_type(3), __comp);
0781 std::__sort3<_AlgPolicy, _Compare>(
0782 __first + (__half_len - 1), __first + __half_len, __first + (__half_len + 1), __comp);
0783 _Ops::iter_swap(__first, __first + __half_len);
0784 } else {
0785 std::__sort3<_AlgPolicy, _Compare>(__first + __half_len, __first, __last - difference_type(1), __comp);
0786 }
0787 }
0788
0789
0790
0791
0792
0793
0794
0795
0796 if (!__leftmost && !__comp(*(__first - difference_type(1)), *__first)) {
0797 __first = std::__partition_with_equals_on_left<_AlgPolicy, _RandomAccessIterator, _Comp_ref>(
0798 __first, __last, _Comp_ref(__comp));
0799 continue;
0800 }
0801
0802 auto __ret = _UseBitSetPartition
0803 ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp)
0804 : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(
0805 __first, __last, __comp);
0806 _RandomAccessIterator __i = __ret.first;
0807
0808
0809 if (__ret.second) {
0810 bool __fs = std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__first, __i, __comp);
0811 if (std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp)) {
0812 if (__fs)
0813 return;
0814 __last = __i;
0815 continue;
0816 } else {
0817 if (__fs) {
0818 __first = ++__i;
0819 continue;
0820 }
0821 }
0822 }
0823
0824 std::__introsort<_AlgPolicy, _Compare, _RandomAccessIterator, _UseBitSetPartition>(
0825 __first, __i, __comp, __depth, __leftmost);
0826 __leftmost = false;
0827 __first = ++__i;
0828 }
0829 }
0830
0831 template <typename _Number>
0832 inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) {
0833 if (__n == 0)
0834 return 0;
0835 if (sizeof(__n) <= sizeof(unsigned))
0836 return sizeof(unsigned) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned>(__n));
0837 if (sizeof(__n) <= sizeof(unsigned long))
0838 return sizeof(unsigned long) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned long>(__n));
0839 if (sizeof(__n) <= sizeof(unsigned long long))
0840 return sizeof(unsigned long long) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned long long>(__n));
0841
0842 _Number __log2 = 0;
0843 while (__n > 1) {
0844 __log2++;
0845 __n >>= 1;
0846 }
0847 return __log2;
0848 }
0849
0850 template <class _Comp, class _RandomAccessIterator>
0851 void __sort(_RandomAccessIterator, _RandomAccessIterator, _Comp);
0852
0853 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
0854 #if _LIBCPP_HAS_WIDE_CHARACTERS
0855 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
0856 #endif
0857 extern template _LIBCPP_EXPORTED_FROM_ABI void
0858 __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
0859 extern template _LIBCPP_EXPORTED_FROM_ABI void
0860 __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
0861 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<short>&, short*>(short*, short*, __less<short>&);
0862 extern template _LIBCPP_EXPORTED_FROM_ABI void
0863 __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
0864 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<int>&, int*>(int*, int*, __less<int>&);
0865 extern template _LIBCPP_EXPORTED_FROM_ABI void
0866 __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
0867 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long>&, long*>(long*, long*, __less<long>&);
0868 extern template _LIBCPP_EXPORTED_FROM_ABI void
0869 __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
0870 extern template _LIBCPP_EXPORTED_FROM_ABI void
0871 __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
0872 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long long>&, unsigned long long*>(
0873 unsigned long long*, unsigned long long*, __less<unsigned long long>&);
0874 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
0875 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
0876 extern template _LIBCPP_EXPORTED_FROM_ABI void
0877 __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
0878
0879 template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
0880 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
0881 __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
0882 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
0883 difference_type __depth_limit = 2 * std::__log2i(__last - __first);
0884
0885
0886
0887
0888 std::__introsort<_AlgPolicy, _Comp&, _RandomAccessIterator, __use_branchless_sort<_Comp, _RandomAccessIterator> >(
0889 __first, __last, __comp, __depth_limit);
0890 }
0891
0892 template <class _Type, class... _Options>
0893 using __is_any_of _LIBCPP_NODEBUG = _Or<is_same<_Type, _Options>...>;
0894
0895 template <class _Type>
0896 using __sort_is_specialized_in_library _LIBCPP_NODEBUG = __is_any_of<
0897 _Type,
0898 char,
0899 #if _LIBCPP_HAS_WIDE_CHARACTERS
0900 wchar_t,
0901 #endif
0902 signed char,
0903 unsigned char,
0904 short,
0905 unsigned short,
0906 int,
0907 unsigned int,
0908 long,
0909 unsigned long,
0910 long long,
0911 unsigned long long,
0912 float,
0913 double,
0914 long double>;
0915
0916 template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
0917 _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) {
0918 __less<_Type> __comp;
0919 std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
0920 }
0921
0922 template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
0923 _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<_Type>&) {
0924 __less<_Type> __comp;
0925 std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
0926 }
0927
0928 #if _LIBCPP_STD_VER >= 14
0929 template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
0930 _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<>&) {
0931 __less<_Type> __comp;
0932 std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
0933 }
0934 #endif
0935
0936 #if _LIBCPP_STD_VER >= 20
0937 template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
0938 _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges::less&) {
0939 __less<_Type> __comp;
0940 std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
0941 }
0942 #endif
0943
0944 template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
0945 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
0946 __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
0947 std::__debug_randomize_range<_AlgPolicy>(__first, __last);
0948
0949 if (__libcpp_is_constant_evaluated()) {
0950 std::__partial_sort<_AlgPolicy>(
0951 std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__last), __comp);
0952 } else {
0953 std::__sort_dispatch<_AlgPolicy>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp);
0954 }
0955 std::__check_strict_weak_ordering_sorted(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp);
0956 }
0957
0958 template <class _RandomAccessIterator, class _Comp>
0959 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
0960 sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
0961 std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
0962 }
0963
0964 template <class _RandomAccessIterator>
0965 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
0966 sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
0967 std::sort(__first, __last, __less<>());
0968 }
0969
0970 _LIBCPP_END_NAMESPACE_STD
0971
0972 _LIBCPP_POP_MACROS
0973
0974 #endif