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