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 //===----------------------------------------------------------------------===//
8 
9 #ifndef _LIBCPP___ALGORITHM_SORT_H
10 #define _LIBCPP___ALGORITHM_SORT_H
11 
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/desugars_to.h>
31 #include <__type_traits/disjunction.h>
32 #include <__type_traits/enable_if.h>
33 #include <__type_traits/is_arithmetic.h>
34 #include <__type_traits/is_constant_evaluated.h>
35 #include <__type_traits/is_same.h>
36 #include <__type_traits/is_trivially_copyable.h>
37 #include <__type_traits/remove_cvref.h>
38 #include <__utility/move.h>
39 #include <__utility/pair.h>
40 #include <climits>
41 #include <cstdint>
42 
43 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
44 #  pragma GCC system_header
45 #endif
46 
47 _LIBCPP_PUSH_MACROS
48 #include <__undef_macros>
49 
50 _LIBCPP_BEGIN_NAMESPACE_STD
51 
52 template <class _Compare, class _Iter, class _Tp = typename iterator_traits<_Iter>::value_type>
53 inline const bool __use_branchless_sort =
54     __libcpp_is_contiguous_iterator<_Iter>::value && __is_cheap_to_copy<_Tp> && is_arithmetic<_Tp>::value &&
55     (__desugars_to_v<__less_tag, __remove_cvref_t<_Compare>, _Tp, _Tp> ||
56      __desugars_to_v<__greater_tag, __remove_cvref_t<_Compare>, _Tp, _Tp>);
57 
58 namespace __detail {
59 
60 // Size in bits for the bitset in use.
61 enum { __block_size = sizeof(uint64_t) * 8 };
62 
63 } // namespace __detail
64 
65 // Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary.
66 template <class _Compare, class _RandomAccessIterator>
67 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__cond_swap(_RandomAccessIterator __x,_RandomAccessIterator __y,_Compare __c)68 __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) {
69   // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`).
70   using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
71   bool __r         = __c(*__x, *__y);
72   value_type __tmp = __r ? *__x : *__y;
73   *__y             = __r ? *__y : *__x;
74   *__x             = __tmp;
75   return !__r;
76 }
77 
78 // Ensures that *__x, *__y and *__z are ordered according to the comparator __c,
79 // under the assumption that *__y and *__z are already ordered.
80 template <class _Compare, class _RandomAccessIterator>
81 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__partially_sorted_swap(_RandomAccessIterator __x,_RandomAccessIterator __y,_RandomAccessIterator __z,_Compare __c)82 __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _RandomAccessIterator __z, _Compare __c) {
83   // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`).
84   using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
85   bool __r1        = __c(*__z, *__x);
86   value_type __tmp = __r1 ? *__z : *__x;
87   *__z             = __r1 ? *__x : *__z;
88   bool __r2        = __c(__tmp, *__y);
89   *__x             = __r2 ? *__x : *__y;
90   *__y             = __r2 ? *__y : __tmp;
91   return !__r1 || !__r2;
92 }
93 
94 // stable, 2-3 compares, 0-2 swaps
95 
96 template <class,
97           class _Compare,
98           class _RandomAccessIterator,
99           __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
100 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__sort3(_RandomAccessIterator __x1,_RandomAccessIterator __x2,_RandomAccessIterator __x3,_Compare __c)101 __sort3(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _Compare __c) {
102   bool __swapped1 = std::__cond_swap<_Compare>(__x2, __x3, __c);
103   bool __swapped2 = std::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c);
104   return __swapped1 || __swapped2;
105 }
106 
107 template <class _AlgPolicy,
108           class _Compare,
109           class _RandomAccessIterator,
110           __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
111 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__sort3(_RandomAccessIterator __x,_RandomAccessIterator __y,_RandomAccessIterator __z,_Compare __c)112 __sort3(_RandomAccessIterator __x, _RandomAccessIterator __y, _RandomAccessIterator __z, _Compare __c) {
113   using _Ops = _IterOps<_AlgPolicy>;
114 
115   if (!__c(*__y, *__x)) // if x <= y
116   {
117     if (!__c(*__z, *__y))        // if y <= z
118       return false;              // x <= y && y <= z
119                                  // x <= y && y > z
120     _Ops::iter_swap(__y, __z);   // x <= z && y < z
121     if (__c(*__y, *__x))         // if x > y
122       _Ops::iter_swap(__x, __y); // x < y && y <= z
123     return true;                 // x <= y && y < z
124   }
125   if (__c(*__z, *__y)) // x > y, if y > z
126   {
127     _Ops::iter_swap(__x, __z); // x < y && y < z
128     return true;
129   }
130   _Ops::iter_swap(__x, __y); // x > y && y <= z
131   // x < y && x <= z
132   if (__c(*__z, *__y))         // if y > z
133     _Ops::iter_swap(__y, __z); // x <= y && y < z
134   return true;
135 } // x <= y && y <= z
136 
137 // stable, 3-6 compares, 0-5 swaps
138 
139 template <class,
140           class _Compare,
141           class _RandomAccessIterator,
142           __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
143 inline _LIBCPP_HIDE_FROM_ABI void
__sort4(_RandomAccessIterator __x1,_RandomAccessIterator __x2,_RandomAccessIterator __x3,_RandomAccessIterator __x4,_Compare __c)144 __sort4(_RandomAccessIterator __x1,
145         _RandomAccessIterator __x2,
146         _RandomAccessIterator __x3,
147         _RandomAccessIterator __x4,
148         _Compare __c) {
149   std::__cond_swap<_Compare>(__x1, __x3, __c);
150   std::__cond_swap<_Compare>(__x2, __x4, __c);
151   std::__cond_swap<_Compare>(__x1, __x2, __c);
152   std::__cond_swap<_Compare>(__x3, __x4, __c);
153   std::__cond_swap<_Compare>(__x2, __x3, __c);
154 }
155 
156 template <class _AlgPolicy,
157           class _Compare,
158           class _RandomAccessIterator,
159           __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
160 inline _LIBCPP_HIDE_FROM_ABI void
__sort4(_RandomAccessIterator __x1,_RandomAccessIterator __x2,_RandomAccessIterator __x3,_RandomAccessIterator __x4,_Compare __c)161 __sort4(_RandomAccessIterator __x1,
162         _RandomAccessIterator __x2,
163         _RandomAccessIterator __x3,
164         _RandomAccessIterator __x4,
165         _Compare __c) {
166   using _Ops = _IterOps<_AlgPolicy>;
167   std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c);
168   if (__c(*__x4, *__x3)) {
169     _Ops::iter_swap(__x3, __x4);
170     if (__c(*__x3, *__x2)) {
171       _Ops::iter_swap(__x2, __x3);
172       if (__c(*__x2, *__x1)) {
173         _Ops::iter_swap(__x1, __x2);
174       }
175     }
176   }
177 }
178 
179 // stable, 4-10 compares, 0-9 swaps
180 
181 template <class _AlgPolicy,
182           class _Compare,
183           class _RandomAccessIterator,
184           __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
185 inline _LIBCPP_HIDE_FROM_ABI void
__sort5(_RandomAccessIterator __x1,_RandomAccessIterator __x2,_RandomAccessIterator __x3,_RandomAccessIterator __x4,_RandomAccessIterator __x5,_Compare __c)186 __sort5(_RandomAccessIterator __x1,
187         _RandomAccessIterator __x2,
188         _RandomAccessIterator __x3,
189         _RandomAccessIterator __x4,
190         _RandomAccessIterator __x5,
191         _Compare __c) {
192   std::__cond_swap<_Compare>(__x1, __x2, __c);
193   std::__cond_swap<_Compare>(__x4, __x5, __c);
194   std::__partially_sorted_swap<_Compare>(__x3, __x4, __x5, __c);
195   std::__cond_swap<_Compare>(__x2, __x5, __c);
196   std::__partially_sorted_swap<_Compare>(__x1, __x3, __x4, __c);
197   std::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c);
198 }
199 
200 template <class _AlgPolicy,
201           class _Compare,
202           class _RandomAccessIterator,
203           __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>, int> = 0>
204 inline _LIBCPP_HIDE_FROM_ABI void
__sort5(_RandomAccessIterator __x1,_RandomAccessIterator __x2,_RandomAccessIterator __x3,_RandomAccessIterator __x4,_RandomAccessIterator __x5,_Compare __comp)205 __sort5(_RandomAccessIterator __x1,
206         _RandomAccessIterator __x2,
207         _RandomAccessIterator __x3,
208         _RandomAccessIterator __x4,
209         _RandomAccessIterator __x5,
210         _Compare __comp) {
211   using _Ops = _IterOps<_AlgPolicy>;
212 
213   std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __comp);
214   if (__comp(*__x5, *__x4)) {
215     _Ops::iter_swap(__x4, __x5);
216     if (__comp(*__x4, *__x3)) {
217       _Ops::iter_swap(__x3, __x4);
218       if (__comp(*__x3, *__x2)) {
219         _Ops::iter_swap(__x2, __x3);
220         if (__comp(*__x2, *__x1)) {
221           _Ops::iter_swap(__x1, __x2);
222         }
223       }
224     }
225   }
226 }
227 
228 // Assumes size > 0
229 template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
230 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
__selection_sort(_BidirectionalIterator __first,_BidirectionalIterator __last,_Compare __comp)231 __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
232   _BidirectionalIterator __lm1 = __last;
233   for (--__lm1; __first != __lm1; ++__first) {
234     _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp);
235     if (__i != __first)
236       _IterOps<_AlgPolicy>::iter_swap(__first, __i);
237   }
238 }
239 
240 // Sort the iterator range [__first, __last) using the comparator __comp using
241 // the insertion sort algorithm.
242 template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
243 _LIBCPP_HIDE_FROM_ABI void
__insertion_sort(_BidirectionalIterator __first,_BidirectionalIterator __last,_Compare __comp)244 __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
245   using _Ops = _IterOps<_AlgPolicy>;
246 
247   typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
248   if (__first == __last)
249     return;
250   _BidirectionalIterator __i = __first;
251   for (++__i; __i != __last; ++__i) {
252     _BidirectionalIterator __j = __i;
253     --__j;
254     if (__comp(*__i, *__j)) {
255       value_type __t(_Ops::__iter_move(__i));
256       _BidirectionalIterator __k = __j;
257       __j                        = __i;
258       do {
259         *__j = _Ops::__iter_move(__k);
260         __j  = __k;
261       } while (__j != __first && __comp(__t, *--__k));
262       *__j = std::move(__t);
263     }
264   }
265 }
266 
267 // Sort the iterator range [__first, __last) using the comparator __comp using
268 // the insertion sort algorithm.  Insertion sort has two loops, outer and inner.
269 // The implementation below has no bounds check (unguarded) for the inner loop.
270 // Assumes that there is an element in the position (__first - 1) and that each
271 // element in the input range is greater or equal to the element at __first - 1.
272 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
273 _LIBCPP_HIDE_FROM_ABI void
__insertion_sort_unguarded(_RandomAccessIterator const __first,_RandomAccessIterator __last,_Compare __comp)274 __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIterator __last, _Compare __comp) {
275   using _Ops = _IterOps<_AlgPolicy>;
276   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
277   typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
278   if (__first == __last)
279     return;
280   const _RandomAccessIterator __leftmost = __first - difference_type(1);
281   (void)__leftmost; // can be unused when assertions are disabled
282   for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) {
283     _RandomAccessIterator __j = __i - difference_type(1);
284     if (__comp(*__i, *__j)) {
285       value_type __t(_Ops::__iter_move(__i));
286       _RandomAccessIterator __k = __j;
287       __j                       = __i;
288       do {
289         *__j = _Ops::__iter_move(__k);
290         __j  = __k;
291         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
292             __k != __leftmost,
293             "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
294       } while (__comp(__t, *--__k)); // No need for bounds check due to the assumption stated above.
295       *__j = std::move(__t);
296     }
297   }
298 }
299 
300 template <class _AlgPolicy, class _Comp, class _RandomAccessIterator>
301 _LIBCPP_HIDE_FROM_ABI bool
__insertion_sort_incomplete(_RandomAccessIterator __first,_RandomAccessIterator __last,_Comp __comp)302 __insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
303   using _Ops = _IterOps<_AlgPolicy>;
304 
305   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
306   switch (__last - __first) {
307   case 0:
308   case 1:
309     return true;
310   case 2:
311     if (__comp(*--__last, *__first))
312       _Ops::iter_swap(__first, __last);
313     return true;
314   case 3:
315     std::__sort3<_AlgPolicy, _Comp>(__first, __first + difference_type(1), --__last, __comp);
316     return true;
317   case 4:
318     std::__sort4<_AlgPolicy, _Comp>(
319         __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
320     return true;
321   case 5:
322     std::__sort5<_AlgPolicy, _Comp>(
323         __first,
324         __first + difference_type(1),
325         __first + difference_type(2),
326         __first + difference_type(3),
327         --__last,
328         __comp);
329     return true;
330   }
331   typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
332   _RandomAccessIterator __j = __first + difference_type(2);
333   std::__sort3<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp);
334   const unsigned __limit = 8;
335   unsigned __count       = 0;
336   for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) {
337     if (__comp(*__i, *__j)) {
338       value_type __t(_Ops::__iter_move(__i));
339       _RandomAccessIterator __k = __j;
340       __j                       = __i;
341       do {
342         *__j = _Ops::__iter_move(__k);
343         __j  = __k;
344       } while (__j != __first && __comp(__t, *--__k));
345       *__j = std::move(__t);
346       if (++__count == __limit)
347         return ++__i == __last;
348     }
349     __j = __i;
350   }
351   return true;
352 }
353 
354 template <class _AlgPolicy, class _RandomAccessIterator>
__swap_bitmap_pos(_RandomAccessIterator __first,_RandomAccessIterator __last,uint64_t & __left_bitset,uint64_t & __right_bitset)355 inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos(
356     _RandomAccessIterator __first, _RandomAccessIterator __last, uint64_t& __left_bitset, uint64_t& __right_bitset) {
357   using _Ops = _IterOps<_AlgPolicy>;
358   typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
359   // Swap one pair on each iteration as long as both bitsets have at least one
360   // element for swapping.
361   while (__left_bitset != 0 && __right_bitset != 0) {
362     difference_type __tz_left  = __libcpp_ctz(__left_bitset);
363     __left_bitset              = __libcpp_blsr(__left_bitset);
364     difference_type __tz_right = __libcpp_ctz(__right_bitset);
365     __right_bitset             = __libcpp_blsr(__right_bitset);
366     _Ops::iter_swap(__first + __tz_left, __last - __tz_right);
367   }
368 }
369 
370 template <class _Compare,
371           class _RandomAccessIterator,
372           class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
373 inline _LIBCPP_HIDE_FROM_ABI void
__populate_left_bitset(_RandomAccessIterator __first,_Compare __comp,_ValueType & __pivot,uint64_t & __left_bitset)374 __populate_left_bitset(_RandomAccessIterator __first, _Compare __comp, _ValueType& __pivot, uint64_t& __left_bitset) {
375   // Possible vectorization. With a proper "-march" flag, the following loop
376   // will be compiled into a set of SIMD instructions.
377   _RandomAccessIterator __iter = __first;
378   for (int __j = 0; __j < __detail::__block_size;) {
379     bool __comp_result = !__comp(*__iter, __pivot);
380     __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
381     __j++;
382     ++__iter;
383   }
384 }
385 
386 template <class _Compare,
387           class _RandomAccessIterator,
388           class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
389 inline _LIBCPP_HIDE_FROM_ABI void
__populate_right_bitset(_RandomAccessIterator __lm1,_Compare __comp,_ValueType & __pivot,uint64_t & __right_bitset)390 __populate_right_bitset(_RandomAccessIterator __lm1, _Compare __comp, _ValueType& __pivot, uint64_t& __right_bitset) {
391   // Possible vectorization. With a proper "-march" flag, the following loop
392   // will be compiled into a set of SIMD instructions.
393   _RandomAccessIterator __iter = __lm1;
394   for (int __j = 0; __j < __detail::__block_size;) {
395     bool __comp_result = __comp(*__iter, __pivot);
396     __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
397     __j++;
398     --__iter;
399   }
400 }
401 
402 template <class _AlgPolicy,
403           class _Compare,
404           class _RandomAccessIterator,
405           class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type>
__bitset_partition_partial_blocks(_RandomAccessIterator & __first,_RandomAccessIterator & __lm1,_Compare __comp,_ValueType & __pivot,uint64_t & __left_bitset,uint64_t & __right_bitset)406 inline _LIBCPP_HIDE_FROM_ABI void __bitset_partition_partial_blocks(
407     _RandomAccessIterator& __first,
408     _RandomAccessIterator& __lm1,
409     _Compare __comp,
410     _ValueType& __pivot,
411     uint64_t& __left_bitset,
412     uint64_t& __right_bitset) {
413   typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
414   difference_type __remaining_len = __lm1 - __first + 1;
415   difference_type __l_size;
416   difference_type __r_size;
417   if (__left_bitset == 0 && __right_bitset == 0) {
418     __l_size = __remaining_len / 2;
419     __r_size = __remaining_len - __l_size;
420   } else if (__left_bitset == 0) {
421     // We know at least one side is a full block.
422     __l_size = __remaining_len - __detail::__block_size;
423     __r_size = __detail::__block_size;
424   } else { // if (__right_bitset == 0)
425     __l_size = __detail::__block_size;
426     __r_size = __remaining_len - __detail::__block_size;
427   }
428   // Record the comparison outcomes for the elements currently on the left side.
429   if (__left_bitset == 0) {
430     _RandomAccessIterator __iter = __first;
431     for (int __j = 0; __j < __l_size; __j++) {
432       bool __comp_result = !__comp(*__iter, __pivot);
433       __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
434       ++__iter;
435     }
436   }
437   // Record the comparison outcomes for the elements currently on the right
438   // side.
439   if (__right_bitset == 0) {
440     _RandomAccessIterator __iter = __lm1;
441     for (int __j = 0; __j < __r_size; __j++) {
442       bool __comp_result = __comp(*__iter, __pivot);
443       __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j);
444       --__iter;
445     }
446   }
447   std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset);
448   __first += (__left_bitset == 0) ? __l_size : 0;
449   __lm1 -= (__right_bitset == 0) ? __r_size : 0;
450 }
451 
452 template <class _AlgPolicy, class _RandomAccessIterator>
__swap_bitmap_pos_within(_RandomAccessIterator & __first,_RandomAccessIterator & __lm1,uint64_t & __left_bitset,uint64_t & __right_bitset)453 inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos_within(
454     _RandomAccessIterator& __first, _RandomAccessIterator& __lm1, uint64_t& __left_bitset, uint64_t& __right_bitset) {
455   using _Ops = _IterOps<_AlgPolicy>;
456   typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
457   if (__left_bitset) {
458     // Swap within the left side.  Need to find set positions in the reverse
459     // order.
460     while (__left_bitset != 0) {
461       difference_type __tz_left = __detail::__block_size - 1 - __libcpp_clz(__left_bitset);
462       __left_bitset &= (static_cast<uint64_t>(1) << __tz_left) - 1;
463       _RandomAccessIterator __it = __first + __tz_left;
464       if (__it != __lm1) {
465         _Ops::iter_swap(__it, __lm1);
466       }
467       --__lm1;
468     }
469     __first = __lm1 + difference_type(1);
470   } else if (__right_bitset) {
471     // Swap within the right side.  Need to find set positions in the reverse
472     // order.
473     while (__right_bitset != 0) {
474       difference_type __tz_right = __detail::__block_size - 1 - __libcpp_clz(__right_bitset);
475       __right_bitset &= (static_cast<uint64_t>(1) << __tz_right) - 1;
476       _RandomAccessIterator __it = __lm1 - __tz_right;
477       if (__it != __first) {
478         _Ops::iter_swap(__it, __first);
479       }
480       ++__first;
481     }
482   }
483 }
484 
485 // Partition [__first, __last) using the comparator __comp.  *__first has the
486 // chosen pivot.  Elements that are equivalent are kept to the left of the
487 // pivot.  Returns the iterator for the pivot and a bool value which is true if
488 // the provided range is already sorted, false otherwise.  We assume that the
489 // length of the range is at least three elements.
490 //
491 // __bitset_partition uses bitsets for storing outcomes of the comparisons
492 // between the pivot and other elements.
493 template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
494 _LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool>
__bitset_partition(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)495 __bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
496   using _Ops = _IterOps<_AlgPolicy>;
497   typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
498   typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
499   _LIBCPP_ASSERT_INTERNAL(__last - __first >= difference_type(3), "");
500   const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
501   const _RandomAccessIterator __end   = __last;
502   (void)__end; //
503 
504   value_type __pivot(_Ops::__iter_move(__first));
505   // Find the first element greater than the pivot.
506   if (__comp(__pivot, *(__last - difference_type(1)))) {
507     // Not guarded since we know the last element is greater than the pivot.
508     do {
509       ++__first;
510       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
511           __first != __end,
512           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
513     } while (!__comp(__pivot, *__first));
514   } else {
515     while (++__first < __last && !__comp(__pivot, *__first)) {
516     }
517   }
518   // Find the last element less than or equal to the pivot.
519   if (__first < __last) {
520     // It will be always guarded because __introsort will do the median-of-three
521     // before calling this.
522     do {
523       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
524           __last != __begin,
525           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
526       --__last;
527     } while (__comp(__pivot, *__last));
528   }
529   // If the first element greater than the pivot is at or after the
530   // last element less than or equal to the pivot, then we have covered the
531   // entire range without swapping elements.  This implies the range is already
532   // partitioned.
533   bool __already_partitioned = __first >= __last;
534   if (!__already_partitioned) {
535     _Ops::iter_swap(__first, __last);
536     ++__first;
537   }
538 
539   // In [__first, __last) __last is not inclusive. From now on, it uses last
540   // minus one to be inclusive on both sides.
541   _RandomAccessIterator __lm1 = __last - difference_type(1);
542   uint64_t __left_bitset      = 0;
543   uint64_t __right_bitset     = 0;
544 
545   // Reminder: length = __lm1 - __first + 1.
546   while (__lm1 - __first >= 2 * __detail::__block_size - 1) {
547     // Record the comparison outcomes for the elements currently on the left
548     // side.
549     if (__left_bitset == 0)
550       std::__populate_left_bitset<_Compare>(__first, __comp, __pivot, __left_bitset);
551     // Record the comparison outcomes for the elements currently on the right
552     // side.
553     if (__right_bitset == 0)
554       std::__populate_right_bitset<_Compare>(__lm1, __comp, __pivot, __right_bitset);
555     // Swap the elements recorded to be the candidates for swapping in the
556     // bitsets.
557     std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset);
558     // Only advance the iterator if all the elements that need to be moved to
559     // other side were moved.
560     __first += (__left_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0);
561     __lm1 -= (__right_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0);
562   }
563   // Now, we have a less-than a block worth of elements on at least one of the
564   // sides.
565   std::__bitset_partition_partial_blocks<_AlgPolicy, _Compare>(
566       __first, __lm1, __comp, __pivot, __left_bitset, __right_bitset);
567   // At least one the bitsets would be empty.  For the non-empty one, we need to
568   // properly partition the elements that appear within that bitset.
569   std::__swap_bitmap_pos_within<_AlgPolicy>(__first, __lm1, __left_bitset, __right_bitset);
570 
571   // Move the pivot to its correct position.
572   _RandomAccessIterator __pivot_pos = __first - difference_type(1);
573   if (__begin != __pivot_pos) {
574     *__begin = _Ops::__iter_move(__pivot_pos);
575   }
576   *__pivot_pos = std::move(__pivot);
577   return std::make_pair(__pivot_pos, __already_partitioned);
578 }
579 
580 // Partition [__first, __last) using the comparator __comp.  *__first has the
581 // chosen pivot.  Elements that are equivalent are kept to the right of the
582 // pivot.  Returns the iterator for the pivot and a bool value which is true if
583 // the provided range is already sorted, false otherwise.  We assume that the
584 // length of the range is at least three elements.
585 template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
586 _LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool>
__partition_with_equals_on_right(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)587 __partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
588   using _Ops = _IterOps<_AlgPolicy>;
589   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
590   typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
591   _LIBCPP_ASSERT_INTERNAL(__last - __first >= difference_type(3), "");
592   const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
593   const _RandomAccessIterator __end   = __last;
594   (void)__end; //
595   value_type __pivot(_Ops::__iter_move(__first));
596   // Find the first element greater or equal to the pivot.  It will be always
597   // guarded because __introsort will do the median-of-three before calling
598   // this.
599   do {
600     ++__first;
601     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
602         __first != __end,
603         "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
604   } while (__comp(*__first, __pivot));
605 
606   // Find the last element less than the pivot.
607   if (__begin == __first - difference_type(1)) {
608     while (__first < __last && !__comp(*--__last, __pivot))
609       ;
610   } else {
611     // Guarded.
612     do {
613       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
614           __last != __begin,
615           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
616       --__last;
617     } while (!__comp(*__last, __pivot));
618   }
619 
620   // If the first element greater than or equal to the pivot is at or after the
621   // last element less than the pivot, then we have covered the entire range
622   // without swapping elements.  This implies the range is already partitioned.
623   bool __already_partitioned = __first >= __last;
624   // Go through the remaining elements.  Swap pairs of elements (one to the
625   // right of the pivot and the other to left of the pivot) that are not on the
626   // correct side of the pivot.
627   while (__first < __last) {
628     _Ops::iter_swap(__first, __last);
629     do {
630       ++__first;
631       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
632           __first != __end,
633           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
634     } while (__comp(*__first, __pivot));
635     do {
636       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
637           __last != __begin,
638           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
639       --__last;
640     } while (!__comp(*__last, __pivot));
641   }
642   // Move the pivot to its correct position.
643   _RandomAccessIterator __pivot_pos = __first - difference_type(1);
644   if (__begin != __pivot_pos) {
645     *__begin = _Ops::__iter_move(__pivot_pos);
646   }
647   *__pivot_pos = std::move(__pivot);
648   return std::make_pair(__pivot_pos, __already_partitioned);
649 }
650 
651 // Similar to the above function.  Elements equivalent to the pivot are put to
652 // the left of the pivot.  Returns the iterator to the pivot element.
653 template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
654 _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
__partition_with_equals_on_left(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)655 __partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
656   using _Ops = _IterOps<_AlgPolicy>;
657   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
658   typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type;
659   const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around
660   const _RandomAccessIterator __end   = __last;
661   (void)__end; //
662   value_type __pivot(_Ops::__iter_move(__first));
663   if (__comp(__pivot, *(__last - difference_type(1)))) {
664     // Guarded.
665     do {
666       ++__first;
667       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
668           __first != __end,
669           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
670     } while (!__comp(__pivot, *__first));
671   } else {
672     while (++__first < __last && !__comp(__pivot, *__first)) {
673     }
674   }
675 
676   if (__first < __last) {
677     // It will be always guarded because __introsort will do the
678     // median-of-three before calling this.
679     do {
680       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
681           __last != __begin,
682           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
683       --__last;
684     } while (__comp(__pivot, *__last));
685   }
686   while (__first < __last) {
687     _Ops::iter_swap(__first, __last);
688     do {
689       ++__first;
690       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
691           __first != __end,
692           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
693     } while (!__comp(__pivot, *__first));
694     do {
695       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
696           __last != __begin,
697           "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
698       --__last;
699     } while (__comp(__pivot, *__last));
700   }
701   _RandomAccessIterator __pivot_pos = __first - difference_type(1);
702   if (__begin != __pivot_pos) {
703     *__begin = _Ops::__iter_move(__pivot_pos);
704   }
705   *__pivot_pos = std::move(__pivot);
706   return __first;
707 }
708 
709 // The main sorting function.  Implements introsort combined with other ideas:
710 //  - option of using block quick sort for partitioning,
711 //  - guarded and unguarded insertion sort for small lengths,
712 //  - Tuckey's ninther technique for computing the pivot,
713 //  - check on whether partition was not required.
714 // The implementation is partly based on Orson Peters' pattern-defeating
715 // quicksort, published at: <https://github.com/orlp/pdqsort>.
716 template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, bool _UseBitSetPartition>
717 void __introsort(_RandomAccessIterator __first,
718                  _RandomAccessIterator __last,
719                  _Compare __comp,
720                  typename iterator_traits<_RandomAccessIterator>::difference_type __depth,
721                  bool __leftmost = true) {
722   using _Ops = _IterOps<_AlgPolicy>;
723   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
724   using _Comp_ref = __comp_ref_type<_Compare>;
725   // Upper bound for using insertion sort for sorting.
726   _LIBCPP_CONSTEXPR difference_type __limit = 24;
727   // Lower bound for using Tuckey's ninther technique for median computation.
728   _LIBCPP_CONSTEXPR difference_type __ninther_threshold = 128;
729   while (true) {
730     difference_type __len = __last - __first;
731     switch (__len) {
732     case 0:
733     case 1:
734       return;
735     case 2:
736       if (__comp(*--__last, *__first))
737         _Ops::iter_swap(__first, __last);
738       return;
739     case 3:
740       std::__sort3<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp);
741       return;
742     case 4:
743       std::__sort4<_AlgPolicy, _Compare>(
744           __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
745       return;
746     case 5:
747       std::__sort5<_AlgPolicy, _Compare>(
748           __first,
749           __first + difference_type(1),
750           __first + difference_type(2),
751           __first + difference_type(3),
752           --__last,
753           __comp);
754       return;
755     }
756     // Use insertion sort if the length of the range is below the specified limit.
757     if (__len < __limit) {
758       if (__leftmost) {
759         std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
760       } else {
761         std::__insertion_sort_unguarded<_AlgPolicy, _Compare>(__first, __last, __comp);
762       }
763       return;
764     }
765     if (__depth == 0) {
766       // Fallback to heap sort as Introsort suggests.
767       std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp);
768       return;
769     }
770     --__depth;
771     {
772       difference_type __half_len = __len / 2;
773       // Use Tuckey's ninther technique or median of 3 for pivot selection
774       // depending on the length of the range being sorted.
775       if (__len > __ninther_threshold) {
776         std::__sort3<_AlgPolicy, _Compare>(__first, __first + __half_len, __last - difference_type(1), __comp);
777         std::__sort3<_AlgPolicy, _Compare>(
778             __first + difference_type(1), __first + (__half_len - 1), __last - difference_type(2), __comp);
779         std::__sort3<_AlgPolicy, _Compare>(
780             __first + difference_type(2), __first + (__half_len + 1), __last - difference_type(3), __comp);
781         std::__sort3<_AlgPolicy, _Compare>(
782             __first + (__half_len - 1), __first + __half_len, __first + (__half_len + 1), __comp);
783         _Ops::iter_swap(__first, __first + __half_len);
784       } else {
785         std::__sort3<_AlgPolicy, _Compare>(__first + __half_len, __first, __last - difference_type(1), __comp);
786       }
787     }
788     // The elements to the left of the current iterator range are already
789     // sorted.  If the current iterator range to be sorted is not the
790     // leftmost part of the entire iterator range and the pivot is same as
791     // the highest element in the range to the left, then we know that all
792     // the elements in the range [first, pivot] would be equal to the pivot,
793     // assuming the equal elements are put on the left side when
794     // partitioned.  This also means that we do not need to sort the left
795     // side of the partition.
796     if (!__leftmost && !__comp(*(__first - difference_type(1)), *__first)) {
797       __first = std::__partition_with_equals_on_left<_AlgPolicy, _RandomAccessIterator, _Comp_ref>(
798           __first, __last, _Comp_ref(__comp));
799       continue;
800     }
801     // Use bitset partition only if asked for.
802     auto __ret                = _UseBitSetPartition
803                                   ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp)
804                                   : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(
805                          __first, __last, __comp);
806     _RandomAccessIterator __i = __ret.first;
807     // [__first, __i) < *__i and *__i <= [__i+1, __last)
808     // If we were given a perfect partition, see if insertion sort is quick...
809     if (__ret.second) {
810       bool __fs = std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__first, __i, __comp);
811       if (std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp)) {
812         if (__fs)
813           return;
814         __last = __i;
815         continue;
816       } else {
817         if (__fs) {
818           __first = ++__i;
819           continue;
820         }
821       }
822     }
823     // Sort the left partiton recursively and the right partition with tail recursion elimination.
824     std::__introsort<_AlgPolicy, _Compare, _RandomAccessIterator, _UseBitSetPartition>(
825         __first, __i, __comp, __depth, __leftmost);
826     __leftmost = false;
827     __first    = ++__i;
828   }
829 }
830 
831 template <typename _Number>
__log2i(_Number __n)832 inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) {
833   if (__n == 0)
834     return 0;
835   if (sizeof(__n) <= sizeof(unsigned))
836     return sizeof(unsigned) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned>(__n));
837   if (sizeof(__n) <= sizeof(unsigned long))
838     return sizeof(unsigned long) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned long>(__n));
839   if (sizeof(__n) <= sizeof(unsigned long long))
840     return sizeof(unsigned long long) * CHAR_BIT - 1 - __libcpp_clz(static_cast<unsigned long long>(__n));
841 
842   _Number __log2 = 0;
843   while (__n > 1) {
844     __log2++;
845     __n >>= 1;
846   }
847   return __log2;
848 }
849 
850 template <class _Comp, class _RandomAccessIterator>
851 void __sort(_RandomAccessIterator, _RandomAccessIterator, _Comp);
852 
853 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
854 #if _LIBCPP_HAS_WIDE_CHARACTERS
855 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
856 #endif
857 extern template _LIBCPP_EXPORTED_FROM_ABI void
858 __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
859 extern template _LIBCPP_EXPORTED_FROM_ABI void
860 __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
861 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<short>&, short*>(short*, short*, __less<short>&);
862 extern template _LIBCPP_EXPORTED_FROM_ABI void
863 __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
864 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<int>&, int*>(int*, int*, __less<int>&);
865 extern template _LIBCPP_EXPORTED_FROM_ABI void
866 __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
869 __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
870 extern template _LIBCPP_EXPORTED_FROM_ABI void
871 __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
872 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long long>&, unsigned long long*>(
873     unsigned long long*, unsigned long long*, __less<unsigned long long>&);
874 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
875 extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
876 extern template _LIBCPP_EXPORTED_FROM_ABI void
877 __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
878 
879 template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
880 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__sort_dispatch(_RandomAccessIterator __first,_RandomAccessIterator __last,_Comp & __comp)881 __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
882   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
883   difference_type __depth_limit = 2 * std::__log2i(__last - __first);
884 
885   // Only use bitset partitioning for arithmetic types.  We should also check
886   // that the default comparator is in use so that we are sure that there are no
887   // branches in the comparator.
888   std::__introsort<_AlgPolicy, _Comp&, _RandomAccessIterator, __use_branchless_sort<_Comp, _RandomAccessIterator> >(
889       __first, __last, __comp, __depth_limit);
890 }
891 
892 template <class _Type, class... _Options>
893 using __is_any_of = _Or<is_same<_Type, _Options>...>;
894 
895 template <class _Type>
896 using __sort_is_specialized_in_library = __is_any_of<
897     _Type,
898     char,
899 #if _LIBCPP_HAS_WIDE_CHARACTERS
900     wchar_t,
901 #endif
902     signed char,
903     unsigned char,
904     short,
905     unsigned short,
906     int,
907     unsigned int,
908     long,
909     unsigned long,
910     long long,
911     unsigned long long,
912     float,
913     double,
914     long double>;
915 
916 template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
__sort_dispatch(_Type * __first,_Type * __last,__less<> &)917 _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) {
918   __less<_Type> __comp;
919   std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
920 }
921 
922 template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
__sort_dispatch(_Type * __first,_Type * __last,less<_Type> &)923 _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<_Type>&) {
924   __less<_Type> __comp;
925   std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
926 }
927 
928 #if _LIBCPP_STD_VER >= 14
929 template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
__sort_dispatch(_Type * __first,_Type * __last,less<> &)930 _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<>&) {
931   __less<_Type> __comp;
932   std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
933 }
934 #endif
935 
936 #if _LIBCPP_STD_VER >= 20
937 template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
__sort_dispatch(_Type * __first,_Type * __last,ranges::less &)938 _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges::less&) {
939   __less<_Type> __comp;
940   std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
941 }
942 #endif
943 
944 template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
945 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__sort_impl(_RandomAccessIterator __first,_RandomAccessIterator __last,_Comp & __comp)946 __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
947   std::__debug_randomize_range<_AlgPolicy>(__first, __last);
948 
949   if (__libcpp_is_constant_evaluated()) {
950     std::__partial_sort<_AlgPolicy>(
951         std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__last), __comp);
952   } else {
953     std::__sort_dispatch<_AlgPolicy>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp);
954   }
955   std::__check_strict_weak_ordering_sorted(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp);
956 }
957 
958 template <class _RandomAccessIterator, class _Comp>
959 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
sort(_RandomAccessIterator __first,_RandomAccessIterator __last,_Comp __comp)960 sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
961   std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
962 }
963 
964 template <class _RandomAccessIterator>
965 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
sort(_RandomAccessIterator __first,_RandomAccessIterator __last)966 sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
967   std::sort(__first, __last, __less<>());
968 }
969 
970 _LIBCPP_END_NAMESPACE_STD
971 
972 _LIBCPP_POP_MACROS
973 
974 #endif // _LIBCPP___ALGORITHM_SORT_H
975