libstdc++
ranges_algo.h
Go to the documentation of this file.
1// Core algorithmic facilities -*- C++ -*-
2
3// Copyright (C) 2020-2022 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/ranges_algo.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{algorithm}
28 */
29
30#ifndef _RANGES_ALGO_H
31#define _RANGES_ALGO_H 1
32
33#if __cplusplus > 201703L
34
36#include <bits/ranges_util.h>
37#include <bits/uniform_int_dist.h> // concept uniform_random_bit_generator
38
39#if __cpp_lib_concepts
40namespace std _GLIBCXX_VISIBILITY(default)
41{
42_GLIBCXX_BEGIN_NAMESPACE_VERSION
43namespace ranges
44{
45 namespace __detail
46 {
47 template<typename _Comp, typename _Proj>
48 constexpr auto
49 __make_comp_proj(_Comp& __comp, _Proj& __proj)
50 {
51 return [&] (auto&& __lhs, auto&& __rhs) -> bool {
52 using _TL = decltype(__lhs);
53 using _TR = decltype(__rhs);
54 return std::__invoke(__comp,
55 std::__invoke(__proj, std::forward<_TL>(__lhs)),
56 std::__invoke(__proj, std::forward<_TR>(__rhs)));
57 };
58 }
59
60 template<typename _Pred, typename _Proj>
61 constexpr auto
62 __make_pred_proj(_Pred& __pred, _Proj& __proj)
63 {
64 return [&] <typename _Tp> (_Tp&& __arg) -> bool {
65 return std::__invoke(__pred,
66 std::__invoke(__proj, std::forward<_Tp>(__arg)));
67 };
68 }
69 } // namespace __detail
70
71 struct __all_of_fn
72 {
73 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
74 typename _Proj = identity,
75 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
76 constexpr bool
77 operator()(_Iter __first, _Sent __last,
78 _Pred __pred, _Proj __proj = {}) const
79 {
80 for (; __first != __last; ++__first)
81 if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
82 return false;
83 return true;
84 }
85
86 template<input_range _Range, typename _Proj = identity,
87 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
88 _Pred>
89 constexpr bool
90 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
91 {
92 return (*this)(ranges::begin(__r), ranges::end(__r),
93 std::move(__pred), std::move(__proj));
94 }
95 };
96
97 inline constexpr __all_of_fn all_of{};
98
99 struct __any_of_fn
100 {
101 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
102 typename _Proj = identity,
103 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
104 constexpr bool
105 operator()(_Iter __first, _Sent __last,
106 _Pred __pred, _Proj __proj = {}) const
107 {
108 for (; __first != __last; ++__first)
109 if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
110 return true;
111 return false;
112 }
113
114 template<input_range _Range, typename _Proj = identity,
115 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
116 _Pred>
117 constexpr bool
118 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
119 {
120 return (*this)(ranges::begin(__r), ranges::end(__r),
121 std::move(__pred), std::move(__proj));
122 }
123 };
124
125 inline constexpr __any_of_fn any_of{};
126
127 struct __none_of_fn
128 {
129 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
130 typename _Proj = identity,
131 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
132 constexpr bool
133 operator()(_Iter __first, _Sent __last,
134 _Pred __pred, _Proj __proj = {}) const
135 {
136 for (; __first != __last; ++__first)
137 if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
138 return false;
139 return true;
140 }
141
142 template<input_range _Range, typename _Proj = identity,
143 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
144 _Pred>
145 constexpr bool
146 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
147 {
148 return (*this)(ranges::begin(__r), ranges::end(__r),
149 std::move(__pred), std::move(__proj));
150 }
151 };
152
153 inline constexpr __none_of_fn none_of{};
154
155 template<typename _Iter, typename _Fp>
156 struct in_fun_result
157 {
158 [[no_unique_address]] _Iter in;
159 [[no_unique_address]] _Fp fun;
160
161 template<typename _Iter2, typename _F2p>
162 requires convertible_to<const _Iter&, _Iter2>
163 && convertible_to<const _Fp&, _F2p>
164 constexpr
165 operator in_fun_result<_Iter2, _F2p>() const &
166 { return {in, fun}; }
167
168 template<typename _Iter2, typename _F2p>
169 requires convertible_to<_Iter, _Iter2> && convertible_to<_Fp, _F2p>
170 constexpr
171 operator in_fun_result<_Iter2, _F2p>() &&
172 { return {std::move(in), std::move(fun)}; }
173 };
174
175 template<typename _Iter, typename _Fp>
176 using for_each_result = in_fun_result<_Iter, _Fp>;
177
178 struct __for_each_fn
179 {
180 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
181 typename _Proj = identity,
182 indirectly_unary_invocable<projected<_Iter, _Proj>> _Fun>
183 constexpr for_each_result<_Iter, _Fun>
184 operator()(_Iter __first, _Sent __last, _Fun __f, _Proj __proj = {}) const
185 {
186 for (; __first != __last; ++__first)
187 std::__invoke(__f, std::__invoke(__proj, *__first));
188 return { std::move(__first), std::move(__f) };
189 }
190
191 template<input_range _Range, typename _Proj = identity,
192 indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>>
193 _Fun>
194 constexpr for_each_result<borrowed_iterator_t<_Range>, _Fun>
195 operator()(_Range&& __r, _Fun __f, _Proj __proj = {}) const
196 {
197 return (*this)(ranges::begin(__r), ranges::end(__r),
198 std::move(__f), std::move(__proj));
199 }
200 };
201
202 inline constexpr __for_each_fn for_each{};
203
204 template<typename _Iter, typename _Fp>
205 using for_each_n_result = in_fun_result<_Iter, _Fp>;
206
207 struct __for_each_n_fn
208 {
209 template<input_iterator _Iter, typename _Proj = identity,
210 indirectly_unary_invocable<projected<_Iter, _Proj>> _Fun>
211 constexpr for_each_n_result<_Iter, _Fun>
212 operator()(_Iter __first, iter_difference_t<_Iter> __n,
213 _Fun __f, _Proj __proj = {}) const
214 {
215 if constexpr (random_access_iterator<_Iter>)
216 {
217 if (__n <= 0)
218 return {std::move(__first), std::move(__f)};
219 auto __last = __first + __n;
220 return ranges::for_each(std::move(__first), std::move(__last),
221 std::move(__f), std::move(__proj));
222 }
223 else
224 {
225 while (__n-- > 0)
226 {
227 std::__invoke(__f, std::__invoke(__proj, *__first));
228 ++__first;
229 }
230 return {std::move(__first), std::move(__f)};
231 }
232 }
233 };
234
235 inline constexpr __for_each_n_fn for_each_n{};
236
237 // find, find_if and find_if_not are defined in <bits/ranges_util.h>.
238
239 struct __find_first_of_fn
240 {
241 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
242 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
243 typename _Pred = ranges::equal_to,
244 typename _Proj1 = identity, typename _Proj2 = identity>
245 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
246 constexpr _Iter1
247 operator()(_Iter1 __first1, _Sent1 __last1,
248 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
249 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
250 {
251 for (; __first1 != __last1; ++__first1)
252 for (auto __iter = __first2; __iter != __last2; ++__iter)
253 if (std::__invoke(__pred,
254 std::__invoke(__proj1, *__first1),
255 std::__invoke(__proj2, *__iter)))
256 return __first1;
257 return __first1;
258 }
259
260 template<input_range _Range1, forward_range _Range2,
261 typename _Pred = ranges::equal_to,
262 typename _Proj1 = identity, typename _Proj2 = identity>
263 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
264 _Pred, _Proj1, _Proj2>
265 constexpr borrowed_iterator_t<_Range1>
266 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
267 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
268 {
269 return (*this)(ranges::begin(__r1), ranges::end(__r1),
270 ranges::begin(__r2), ranges::end(__r2),
271 std::move(__pred),
272 std::move(__proj1), std::move(__proj2));
273 }
274 };
275
276 inline constexpr __find_first_of_fn find_first_of{};
277
278 struct __count_fn
279 {
280 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
281 typename _Tp, typename _Proj = identity>
282 requires indirect_binary_predicate<ranges::equal_to,
283 projected<_Iter, _Proj>,
284 const _Tp*>
285 constexpr iter_difference_t<_Iter>
286 operator()(_Iter __first, _Sent __last,
287 const _Tp& __value, _Proj __proj = {}) const
288 {
289 iter_difference_t<_Iter> __n = 0;
290 for (; __first != __last; ++__first)
291 if (std::__invoke(__proj, *__first) == __value)
292 ++__n;
293 return __n;
294 }
295
296 template<input_range _Range, typename _Tp, typename _Proj = identity>
297 requires indirect_binary_predicate<ranges::equal_to,
298 projected<iterator_t<_Range>, _Proj>,
299 const _Tp*>
300 constexpr range_difference_t<_Range>
301 operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
302 {
303 return (*this)(ranges::begin(__r), ranges::end(__r),
304 __value, std::move(__proj));
305 }
306 };
307
308 inline constexpr __count_fn count{};
309
310 struct __count_if_fn
311 {
312 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
313 typename _Proj = identity,
314 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
315 constexpr iter_difference_t<_Iter>
316 operator()(_Iter __first, _Sent __last,
317 _Pred __pred, _Proj __proj = {}) const
318 {
319 iter_difference_t<_Iter> __n = 0;
320 for (; __first != __last; ++__first)
321 if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
322 ++__n;
323 return __n;
324 }
325
326 template<input_range _Range,
327 typename _Proj = identity,
328 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
329 _Pred>
330 constexpr range_difference_t<_Range>
331 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
332 {
333 return (*this)(ranges::begin(__r), ranges::end(__r),
334 std::move(__pred), std::move(__proj));
335 }
336 };
337
338 inline constexpr __count_if_fn count_if{};
339
340 // in_in_result, mismatch and search are defined in <bits/ranges_util.h>.
341
342 struct __search_n_fn
343 {
344 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp,
345 typename _Pred = ranges::equal_to, typename _Proj = identity>
346 requires indirectly_comparable<_Iter, const _Tp*, _Pred, _Proj>
347 constexpr subrange<_Iter>
348 operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __count,
349 const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const
350 {
351 if (__count <= 0)
352 return {__first, __first};
353
354 auto __value_comp = [&] <typename _Rp> (_Rp&& __arg) -> bool {
355 return std::__invoke(__pred, std::forward<_Rp>(__arg), __value);
356 };
357 if (__count == 1)
358 {
359 __first = ranges::find_if(std::move(__first), __last,
360 std::move(__value_comp),
361 std::move(__proj));
362 if (__first == __last)
363 return {__first, __first};
364 else
365 {
366 auto __end = __first;
367 return {__first, ++__end};
368 }
369 }
370
371 if constexpr (sized_sentinel_for<_Sent, _Iter>
372 && random_access_iterator<_Iter>)
373 {
374 auto __tail_size = __last - __first;
375 auto __remainder = __count;
376
377 while (__remainder <= __tail_size)
378 {
379 __first += __remainder;
380 __tail_size -= __remainder;
381 auto __backtrack = __first;
382 while (__value_comp(std::__invoke(__proj, *--__backtrack)))
383 {
384 if (--__remainder == 0)
385 return {__first - __count, __first};
386 }
387 __remainder = __count + 1 - (__first - __backtrack);
388 }
389 auto __i = __first + __tail_size;
390 return {__i, __i};
391 }
392 else
393 {
394 __first = ranges::find_if(__first, __last, __value_comp, __proj);
395 while (__first != __last)
396 {
397 auto __n = __count;
398 auto __i = __first;
399 ++__i;
400 while (__i != __last && __n != 1
401 && __value_comp(std::__invoke(__proj, *__i)))
402 {
403 ++__i;
404 --__n;
405 }
406 if (__n == 1)
407 return {__first, __i};
408 if (__i == __last)
409 return {__i, __i};
410 __first = ranges::find_if(++__i, __last, __value_comp, __proj);
411 }
412 return {__first, __first};
413 }
414 }
415
416 template<forward_range _Range, typename _Tp,
417 typename _Pred = ranges::equal_to, typename _Proj = identity>
418 requires indirectly_comparable<iterator_t<_Range>, const _Tp*,
419 _Pred, _Proj>
420 constexpr borrowed_subrange_t<_Range>
421 operator()(_Range&& __r, range_difference_t<_Range> __count,
422 const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const
423 {
424 return (*this)(ranges::begin(__r), ranges::end(__r),
425 std::move(__count), __value,
426 std::move(__pred), std::move(__proj));
427 }
428 };
429
430 inline constexpr __search_n_fn search_n{};
431
432 struct __find_end_fn
433 {
434 template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
435 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
436 typename _Pred = ranges::equal_to,
437 typename _Proj1 = identity, typename _Proj2 = identity>
438 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
439 constexpr subrange<_Iter1>
440 operator()(_Iter1 __first1, _Sent1 __last1,
441 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
442 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
443 {
444 if constexpr (bidirectional_iterator<_Iter1>
445 && bidirectional_iterator<_Iter2>)
446 {
447 auto __i1 = ranges::next(__first1, __last1);
448 auto __i2 = ranges::next(__first2, __last2);
449 auto __rresult
450 = ranges::search(reverse_iterator<_Iter1>{__i1},
451 reverse_iterator<_Iter1>{__first1},
452 reverse_iterator<_Iter2>{__i2},
453 reverse_iterator<_Iter2>{__first2},
454 std::move(__pred),
455 std::move(__proj1), std::move(__proj2));
456 auto __result_first = ranges::end(__rresult).base();
457 auto __result_last = ranges::begin(__rresult).base();
458 if (__result_last == __first1)
459 return {__i1, __i1};
460 else
461 return {__result_first, __result_last};
462 }
463 else
464 {
465 auto __i = ranges::next(__first1, __last1);
466 if (__first2 == __last2)
467 return {__i, __i};
468
469 auto __result_begin = __i;
470 auto __result_end = __i;
471 for (;;)
472 {
473 auto __new_range = ranges::search(__first1, __last1,
474 __first2, __last2,
475 __pred, __proj1, __proj2);
476 auto __new_result_begin = ranges::begin(__new_range);
477 auto __new_result_end = ranges::end(__new_range);
478 if (__new_result_begin == __last1)
479 return {__result_begin, __result_end};
480 else
481 {
482 __result_begin = __new_result_begin;
483 __result_end = __new_result_end;
484 __first1 = __result_begin;
485 ++__first1;
486 }
487 }
488 }
489 }
490
491 template<forward_range _Range1, forward_range _Range2,
492 typename _Pred = ranges::equal_to,
493 typename _Proj1 = identity, typename _Proj2 = identity>
494 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
495 _Pred, _Proj1, _Proj2>
496 constexpr borrowed_subrange_t<_Range1>
497 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
498 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
499 {
500 return (*this)(ranges::begin(__r1), ranges::end(__r1),
501 ranges::begin(__r2), ranges::end(__r2),
502 std::move(__pred),
503 std::move(__proj1), std::move(__proj2));
504 }
505 };
506
507 inline constexpr __find_end_fn find_end{};
508
509 // adjacent_find is defined in <bits/ranges_util.h>.
510
511 struct __is_permutation_fn
512 {
513 template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
514 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
515 typename _Proj1 = identity, typename _Proj2 = identity,
516 indirect_equivalence_relation<projected<_Iter1, _Proj1>,
517 projected<_Iter2, _Proj2>> _Pred
518 = ranges::equal_to>
519 constexpr bool
520 operator()(_Iter1 __first1, _Sent1 __last1,
521 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
522 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
523 {
524 constexpr bool __sized_iters
525 = (sized_sentinel_for<_Sent1, _Iter1>
526 && sized_sentinel_for<_Sent2, _Iter2>);
527 if constexpr (__sized_iters)
528 {
529 auto __d1 = ranges::distance(__first1, __last1);
530 auto __d2 = ranges::distance(__first2, __last2);
531 if (__d1 != __d2)
532 return false;
533 }
534
535 // Efficiently compare identical prefixes: O(N) if sequences
536 // have the same elements in the same order.
537 for (; __first1 != __last1 && __first2 != __last2;
538 ++__first1, (void)++__first2)
539 if (!(bool)std::__invoke(__pred,
540 std::__invoke(__proj1, *__first1),
541 std::__invoke(__proj2, *__first2)))
542 break;
543
544 if constexpr (__sized_iters)
545 {
546 if (__first1 == __last1)
547 return true;
548 }
549 else
550 {
551 auto __d1 = ranges::distance(__first1, __last1);
552 auto __d2 = ranges::distance(__first2, __last2);
553 if (__d1 == 0 && __d2 == 0)
554 return true;
555 if (__d1 != __d2)
556 return false;
557 }
558
559 for (auto __scan = __first1; __scan != __last1; ++__scan)
560 {
561 auto&& __proj_scan = std::__invoke(__proj1, *__scan);
562 auto __comp_scan = [&] <typename _Tp> (_Tp&& __arg) -> bool {
563 return std::__invoke(__pred, __proj_scan,
564 std::forward<_Tp>(__arg));
565 };
566 if (__scan != ranges::find_if(__first1, __scan,
567 __comp_scan, __proj1))
568 continue; // We've seen this one before.
569
570 auto __matches = ranges::count_if(__first2, __last2,
571 __comp_scan, __proj2);
572 if (__matches == 0
573 || ranges::count_if(__scan, __last1,
574 __comp_scan, __proj1) != __matches)
575 return false;
576 }
577 return true;
578 }
579
580 template<forward_range _Range1, forward_range _Range2,
581 typename _Proj1 = identity, typename _Proj2 = identity,
582 indirect_equivalence_relation<
583 projected<iterator_t<_Range1>, _Proj1>,
584 projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
585 constexpr bool
586 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
587 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
588 {
589 return (*this)(ranges::begin(__r1), ranges::end(__r1),
590 ranges::begin(__r2), ranges::end(__r2),
591 std::move(__pred),
592 std::move(__proj1), std::move(__proj2));
593 }
594 };
595
596 inline constexpr __is_permutation_fn is_permutation{};
597
598 template<typename _Iter, typename _Out>
599 using copy_if_result = in_out_result<_Iter, _Out>;
600
601 struct __copy_if_fn
602 {
603 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
604 weakly_incrementable _Out, typename _Proj = identity,
605 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
606 requires indirectly_copyable<_Iter, _Out>
607 constexpr copy_if_result<_Iter, _Out>
608 operator()(_Iter __first, _Sent __last, _Out __result,
609 _Pred __pred, _Proj __proj = {}) const
610 {
611 for (; __first != __last; ++__first)
612 if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
613 {
614 *__result = *__first;
615 ++__result;
616 }
617 return {std::move(__first), std::move(__result)};
618 }
619
620 template<input_range _Range, weakly_incrementable _Out,
621 typename _Proj = identity,
622 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
623 _Pred>
624 requires indirectly_copyable<iterator_t<_Range>, _Out>
625 constexpr copy_if_result<borrowed_iterator_t<_Range>, _Out>
626 operator()(_Range&& __r, _Out __result,
627 _Pred __pred, _Proj __proj = {}) const
628 {
629 return (*this)(ranges::begin(__r), ranges::end(__r),
630 std::move(__result),
631 std::move(__pred), std::move(__proj));
632 }
633 };
634
635 inline constexpr __copy_if_fn copy_if{};
636
637 template<typename _Iter1, typename _Iter2>
638 using swap_ranges_result = in_in_result<_Iter1, _Iter2>;
639
640 struct __swap_ranges_fn
641 {
642 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
643 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2>
644 requires indirectly_swappable<_Iter1, _Iter2>
645 constexpr swap_ranges_result<_Iter1, _Iter2>
646 operator()(_Iter1 __first1, _Sent1 __last1,
647 _Iter2 __first2, _Sent2 __last2) const
648 {
649 for (; __first1 != __last1 && __first2 != __last2;
650 ++__first1, (void)++__first2)
651 ranges::iter_swap(__first1, __first2);
652 return {std::move(__first1), std::move(__first2)};
653 }
654
655 template<input_range _Range1, input_range _Range2>
656 requires indirectly_swappable<iterator_t<_Range1>, iterator_t<_Range2>>
657 constexpr swap_ranges_result<borrowed_iterator_t<_Range1>,
658 borrowed_iterator_t<_Range2>>
659 operator()(_Range1&& __r1, _Range2&& __r2) const
660 {
661 return (*this)(ranges::begin(__r1), ranges::end(__r1),
662 ranges::begin(__r2), ranges::end(__r2));
663 }
664 };
665
666 inline constexpr __swap_ranges_fn swap_ranges{};
667
668 template<typename _Iter, typename _Out>
669 using unary_transform_result = in_out_result<_Iter, _Out>;
670
671 template<typename _Iter1, typename _Iter2, typename _Out>
672 struct in_in_out_result
673 {
674 [[no_unique_address]] _Iter1 in1;
675 [[no_unique_address]] _Iter2 in2;
676 [[no_unique_address]] _Out out;
677
678 template<typename _IIter1, typename _IIter2, typename _OOut>
679 requires convertible_to<const _Iter1&, _IIter1>
680 && convertible_to<const _Iter2&, _IIter2>
681 && convertible_to<const _Out&, _OOut>
682 constexpr
683 operator in_in_out_result<_IIter1, _IIter2, _OOut>() const &
684 { return {in1, in2, out}; }
685
686 template<typename _IIter1, typename _IIter2, typename _OOut>
687 requires convertible_to<_Iter1, _IIter1>
688 && convertible_to<_Iter2, _IIter2>
689 && convertible_to<_Out, _OOut>
690 constexpr
691 operator in_in_out_result<_IIter1, _IIter2, _OOut>() &&
692 { return {std::move(in1), std::move(in2), std::move(out)}; }
693 };
694
695 template<typename _Iter1, typename _Iter2, typename _Out>
696 using binary_transform_result = in_in_out_result<_Iter1, _Iter2, _Out>;
697
698 struct __transform_fn
699 {
700 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
701 weakly_incrementable _Out,
702 copy_constructible _Fp, typename _Proj = identity>
703 requires indirectly_writable<_Out,
704 indirect_result_t<_Fp&,
705 projected<_Iter, _Proj>>>
706 constexpr unary_transform_result<_Iter, _Out>
707 operator()(_Iter __first1, _Sent __last1, _Out __result,
708 _Fp __op, _Proj __proj = {}) const
709 {
710 for (; __first1 != __last1; ++__first1, (void)++__result)
711 *__result = std::__invoke(__op, std::__invoke(__proj, *__first1));
712 return {std::move(__first1), std::move(__result)};
713 }
714
715 template<input_range _Range, weakly_incrementable _Out,
716 copy_constructible _Fp, typename _Proj = identity>
717 requires indirectly_writable<_Out,
718 indirect_result_t<_Fp&,
719 projected<iterator_t<_Range>, _Proj>>>
720 constexpr unary_transform_result<borrowed_iterator_t<_Range>, _Out>
721 operator()(_Range&& __r, _Out __result, _Fp __op, _Proj __proj = {}) const
722 {
723 return (*this)(ranges::begin(__r), ranges::end(__r),
724 std::move(__result),
725 std::move(__op), std::move(__proj));
726 }
727
728 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
729 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
730 weakly_incrementable _Out, copy_constructible _Fp,
731 typename _Proj1 = identity, typename _Proj2 = identity>
732 requires indirectly_writable<_Out,
733 indirect_result_t<_Fp&,
734 projected<_Iter1, _Proj1>,
735 projected<_Iter2, _Proj2>>>
736 constexpr binary_transform_result<_Iter1, _Iter2, _Out>
737 operator()(_Iter1 __first1, _Sent1 __last1,
738 _Iter2 __first2, _Sent2 __last2,
739 _Out __result, _Fp __binary_op,
740 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
741 {
742 for (; __first1 != __last1 && __first2 != __last2;
743 ++__first1, (void)++__first2, ++__result)
744 *__result = std::__invoke(__binary_op,
745 std::__invoke(__proj1, *__first1),
746 std::__invoke(__proj2, *__first2));
747 return {std::move(__first1), std::move(__first2), std::move(__result)};
748 }
749
750 template<input_range _Range1, input_range _Range2,
751 weakly_incrementable _Out, copy_constructible _Fp,
752 typename _Proj1 = identity, typename _Proj2 = identity>
753 requires indirectly_writable<_Out,
754 indirect_result_t<_Fp&,
755 projected<iterator_t<_Range1>, _Proj1>,
756 projected<iterator_t<_Range2>, _Proj2>>>
757 constexpr binary_transform_result<borrowed_iterator_t<_Range1>,
758 borrowed_iterator_t<_Range2>, _Out>
759 operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Fp __binary_op,
760 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
761 {
762 return (*this)(ranges::begin(__r1), ranges::end(__r1),
763 ranges::begin(__r2), ranges::end(__r2),
764 std::move(__result), std::move(__binary_op),
765 std::move(__proj1), std::move(__proj2));
766 }
767 };
768
769 inline constexpr __transform_fn transform{};
770
771 struct __replace_fn
772 {
773 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
774 typename _Tp1, typename _Tp2, typename _Proj = identity>
775 requires indirectly_writable<_Iter, const _Tp2&>
776 && indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>,
777 const _Tp1*>
778 constexpr _Iter
779 operator()(_Iter __first, _Sent __last,
780 const _Tp1& __old_value, const _Tp2& __new_value,
781 _Proj __proj = {}) const
782 {
783 for (; __first != __last; ++__first)
784 if (std::__invoke(__proj, *__first) == __old_value)
785 *__first = __new_value;
786 return __first;
787 }
788
789 template<input_range _Range,
790 typename _Tp1, typename _Tp2, typename _Proj = identity>
791 requires indirectly_writable<iterator_t<_Range>, const _Tp2&>
792 && indirect_binary_predicate<ranges::equal_to,
793 projected<iterator_t<_Range>, _Proj>,
794 const _Tp1*>
795 constexpr borrowed_iterator_t<_Range>
796 operator()(_Range&& __r,
797 const _Tp1& __old_value, const _Tp2& __new_value,
798 _Proj __proj = {}) const
799 {
800 return (*this)(ranges::begin(__r), ranges::end(__r),
801 __old_value, __new_value, std::move(__proj));
802 }
803 };
804
805 inline constexpr __replace_fn replace{};
806
807 struct __replace_if_fn
808 {
809 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
810 typename _Tp, typename _Proj = identity,
811 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
812 requires indirectly_writable<_Iter, const _Tp&>
813 constexpr _Iter
814 operator()(_Iter __first, _Sent __last,
815 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
816 {
817 for (; __first != __last; ++__first)
818 if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
819 *__first = __new_value;
820 return std::move(__first);
821 }
822
823 template<input_range _Range, typename _Tp, typename _Proj = identity,
824 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
825 _Pred>
826 requires indirectly_writable<iterator_t<_Range>, const _Tp&>
827 constexpr borrowed_iterator_t<_Range>
828 operator()(_Range&& __r,
829 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
830 {
831 return (*this)(ranges::begin(__r), ranges::end(__r),
832 std::move(__pred), __new_value, std::move(__proj));
833 }
834 };
835
836 inline constexpr __replace_if_fn replace_if{};
837
838 template<typename _Iter, typename _Out>
839 using replace_copy_result = in_out_result<_Iter, _Out>;
840
841 struct __replace_copy_fn
842 {
843 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
844 typename _Tp1, typename _Tp2, output_iterator<const _Tp2&> _Out,
845 typename _Proj = identity>
846 requires indirectly_copyable<_Iter, _Out>
847 && indirect_binary_predicate<ranges::equal_to,
848 projected<_Iter, _Proj>, const _Tp1*>
849 constexpr replace_copy_result<_Iter, _Out>
850 operator()(_Iter __first, _Sent __last, _Out __result,
851 const _Tp1& __old_value, const _Tp2& __new_value,
852 _Proj __proj = {}) const
853 {
854 for (; __first != __last; ++__first, (void)++__result)
855 if (std::__invoke(__proj, *__first) == __old_value)
856 *__result = __new_value;
857 else
858 *__result = *__first;
859 return {std::move(__first), std::move(__result)};
860 }
861
862 template<input_range _Range, typename _Tp1, typename _Tp2,
863 output_iterator<const _Tp2&> _Out, typename _Proj = identity>
864 requires indirectly_copyable<iterator_t<_Range>, _Out>
865 && indirect_binary_predicate<ranges::equal_to,
866 projected<iterator_t<_Range>, _Proj>,
867 const _Tp1*>
868 constexpr replace_copy_result<borrowed_iterator_t<_Range>, _Out>
869 operator()(_Range&& __r, _Out __result,
870 const _Tp1& __old_value, const _Tp2& __new_value,
871 _Proj __proj = {}) const
872 {
873 return (*this)(ranges::begin(__r), ranges::end(__r),
874 std::move(__result), __old_value,
875 __new_value, std::move(__proj));
876 }
877 };
878
879 inline constexpr __replace_copy_fn replace_copy{};
880
881 template<typename _Iter, typename _Out>
882 using replace_copy_if_result = in_out_result<_Iter, _Out>;
883
884 struct __replace_copy_if_fn
885 {
886 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
887 typename _Tp, output_iterator<const _Tp&> _Out,
888 typename _Proj = identity,
889 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
890 requires indirectly_copyable<_Iter, _Out>
891 constexpr replace_copy_if_result<_Iter, _Out>
892 operator()(_Iter __first, _Sent __last, _Out __result,
893 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
894 {
895 for (; __first != __last; ++__first, (void)++__result)
896 if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
897 *__result = __new_value;
898 else
899 *__result = *__first;
900 return {std::move(__first), std::move(__result)};
901 }
902
903 template<input_range _Range,
904 typename _Tp, output_iterator<const _Tp&> _Out,
905 typename _Proj = identity,
906 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
907 _Pred>
908 requires indirectly_copyable<iterator_t<_Range>, _Out>
909 constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _Out>
910 operator()(_Range&& __r, _Out __result,
911 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
912 {
913 return (*this)(ranges::begin(__r), ranges::end(__r),
914 std::move(__result), std::move(__pred),
915 __new_value, std::move(__proj));
916 }
917 };
918
919 inline constexpr __replace_copy_if_fn replace_copy_if{};
920
921 struct __generate_n_fn
922 {
923 template<input_or_output_iterator _Out, copy_constructible _Fp>
924 requires invocable<_Fp&>
925 && indirectly_writable<_Out, invoke_result_t<_Fp&>>
926 constexpr _Out
927 operator()(_Out __first, iter_difference_t<_Out> __n, _Fp __gen) const
928 {
929 for (; __n > 0; --__n, (void)++__first)
930 *__first = std::__invoke(__gen);
931 return __first;
932 }
933 };
934
935 inline constexpr __generate_n_fn generate_n{};
936
937 struct __generate_fn
938 {
939 template<input_or_output_iterator _Out, sentinel_for<_Out> _Sent,
940 copy_constructible _Fp>
941 requires invocable<_Fp&>
942 && indirectly_writable<_Out, invoke_result_t<_Fp&>>
943 constexpr _Out
944 operator()(_Out __first, _Sent __last, _Fp __gen) const
945 {
946 for (; __first != __last; ++__first)
947 *__first = std::__invoke(__gen);
948 return __first;
949 }
950
951 template<typename _Range, copy_constructible _Fp>
952 requires invocable<_Fp&> && output_range<_Range, invoke_result_t<_Fp&>>
953 constexpr borrowed_iterator_t<_Range>
954 operator()(_Range&& __r, _Fp __gen) const
955 {
956 return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__gen));
957 }
958 };
959
960 inline constexpr __generate_fn generate{};
961
962 struct __remove_if_fn
963 {
964 template<permutable _Iter, sentinel_for<_Iter> _Sent,
965 typename _Proj = identity,
966 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
967 constexpr subrange<_Iter>
968 operator()(_Iter __first, _Sent __last,
969 _Pred __pred, _Proj __proj = {}) const
970 {
971 __first = ranges::find_if(__first, __last, __pred, __proj);
972 if (__first == __last)
973 return {__first, __first};
974
975 auto __result = __first;
976 ++__first;
977 for (; __first != __last; ++__first)
978 if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
979 {
980 *__result = std::move(*__first);
981 ++__result;
982 }
983
984 return {__result, __first};
985 }
986
987 template<forward_range _Range, typename _Proj = identity,
988 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
989 _Pred>
990 requires permutable<iterator_t<_Range>>
991 constexpr borrowed_subrange_t<_Range>
992 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
993 {
994 return (*this)(ranges::begin(__r), ranges::end(__r),
995 std::move(__pred), std::move(__proj));
996 }
997 };
998
999 inline constexpr __remove_if_fn remove_if{};
1000
1001 struct __remove_fn
1002 {
1003 template<permutable _Iter, sentinel_for<_Iter> _Sent,
1004 typename _Tp, typename _Proj = identity>
1005 requires indirect_binary_predicate<ranges::equal_to,
1006 projected<_Iter, _Proj>,
1007 const _Tp*>
1008 constexpr subrange<_Iter>
1009 operator()(_Iter __first, _Sent __last,
1010 const _Tp& __value, _Proj __proj = {}) const
1011 {
1012 auto __pred = [&] (auto&& __arg) -> bool {
1013 return std::forward<decltype(__arg)>(__arg) == __value;
1014 };
1015 return ranges::remove_if(__first, __last,
1016 std::move(__pred), std::move(__proj));
1017 }
1018
1019 template<forward_range _Range, typename _Tp, typename _Proj = identity>
1020 requires permutable<iterator_t<_Range>>
1021 && indirect_binary_predicate<ranges::equal_to,
1022 projected<iterator_t<_Range>, _Proj>,
1023 const _Tp*>
1024 constexpr borrowed_subrange_t<_Range>
1025 operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
1026 {
1027 return (*this)(ranges::begin(__r), ranges::end(__r),
1028 __value, std::move(__proj));
1029 }
1030 };
1031
1032 inline constexpr __remove_fn remove{};
1033
1034 template<typename _Iter, typename _Out>
1035 using remove_copy_if_result = in_out_result<_Iter, _Out>;
1036
1037 struct __remove_copy_if_fn
1038 {
1039 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1040 weakly_incrementable _Out, typename _Proj = identity,
1041 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
1042 requires indirectly_copyable<_Iter, _Out>
1043 constexpr remove_copy_if_result<_Iter, _Out>
1044 operator()(_Iter __first, _Sent __last, _Out __result,
1045 _Pred __pred, _Proj __proj = {}) const
1046 {
1047 for (; __first != __last; ++__first)
1048 if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
1049 {
1050 *__result = *__first;
1051 ++__result;
1052 }
1053 return {std::move(__first), std::move(__result)};
1054 }
1055
1056 template<input_range _Range, weakly_incrementable _Out,
1057 typename _Proj = identity,
1058 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
1059 _Pred>
1060 requires indirectly_copyable<iterator_t<_Range>, _Out>
1061 constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _Out>
1062 operator()(_Range&& __r, _Out __result,
1063 _Pred __pred, _Proj __proj = {}) const
1064 {
1065 return (*this)(ranges::begin(__r), ranges::end(__r),
1066 std::move(__result),
1067 std::move(__pred), std::move(__proj));
1068 }
1069 };
1070
1071 inline constexpr __remove_copy_if_fn remove_copy_if{};
1072
1073 template<typename _Iter, typename _Out>
1074 using remove_copy_result = in_out_result<_Iter, _Out>;
1075
1076 struct __remove_copy_fn
1077 {
1078 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1079 weakly_incrementable _Out, typename _Tp, typename _Proj = identity>
1080 requires indirectly_copyable<_Iter, _Out>
1081 && indirect_binary_predicate<ranges::equal_to,
1082 projected<_Iter, _Proj>,
1083 const _Tp*>
1084 constexpr remove_copy_result<_Iter, _Out>
1085 operator()(_Iter __first, _Sent __last, _Out __result,
1086 const _Tp& __value, _Proj __proj = {}) const
1087 {
1088 for (; __first != __last; ++__first)
1089 if (!(std::__invoke(__proj, *__first) == __value))
1090 {
1091 *__result = *__first;
1092 ++__result;
1093 }
1094 return {std::move(__first), std::move(__result)};
1095 }
1096
1097 template<input_range _Range, weakly_incrementable _Out,
1098 typename _Tp, typename _Proj = identity>
1099 requires indirectly_copyable<iterator_t<_Range>, _Out>
1100 && indirect_binary_predicate<ranges::equal_to,
1101 projected<iterator_t<_Range>, _Proj>,
1102 const _Tp*>
1103 constexpr remove_copy_result<borrowed_iterator_t<_Range>, _Out>
1104 operator()(_Range&& __r, _Out __result,
1105 const _Tp& __value, _Proj __proj = {}) const
1106 {
1107 return (*this)(ranges::begin(__r), ranges::end(__r),
1108 std::move(__result), __value, std::move(__proj));
1109 }
1110 };
1111
1112 inline constexpr __remove_copy_fn remove_copy{};
1113
1114 struct __unique_fn
1115 {
1116 template<permutable _Iter, sentinel_for<_Iter> _Sent,
1117 typename _Proj = identity,
1118 indirect_equivalence_relation<
1119 projected<_Iter, _Proj>> _Comp = ranges::equal_to>
1120 constexpr subrange<_Iter>
1121 operator()(_Iter __first, _Sent __last,
1122 _Comp __comp = {}, _Proj __proj = {}) const
1123 {
1124 __first = ranges::adjacent_find(__first, __last, __comp, __proj);
1125 if (__first == __last)
1126 return {__first, __first};
1127
1128 auto __dest = __first;
1129 ++__first;
1130 while (++__first != __last)
1131 if (!std::__invoke(__comp,
1132 std::__invoke(__proj, *__dest),
1133 std::__invoke(__proj, *__first)))
1134 *++__dest = std::move(*__first);
1135 return {++__dest, __first};
1136 }
1137
1138 template<forward_range _Range, typename _Proj = identity,
1139 indirect_equivalence_relation<
1140 projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
1141 requires permutable<iterator_t<_Range>>
1142 constexpr borrowed_subrange_t<_Range>
1143 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1144 {
1145 return (*this)(ranges::begin(__r), ranges::end(__r),
1146 std::move(__comp), std::move(__proj));
1147 }
1148 };
1149
1150 inline constexpr __unique_fn unique{};
1151
1152 namespace __detail
1153 {
1154 template<typename _Out, typename _Tp>
1155 concept __can_reread_output = input_iterator<_Out>
1156 && same_as<_Tp, iter_value_t<_Out>>;
1157 }
1158
1159 template<typename _Iter, typename _Out>
1160 using unique_copy_result = in_out_result<_Iter, _Out>;
1161
1162 struct __unique_copy_fn
1163 {
1164 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1165 weakly_incrementable _Out, typename _Proj = identity,
1166 indirect_equivalence_relation<
1167 projected<_Iter, _Proj>> _Comp = ranges::equal_to>
1168 requires indirectly_copyable<_Iter, _Out>
1169 && (forward_iterator<_Iter>
1170 || __detail::__can_reread_output<_Out, iter_value_t<_Iter>>
1171 || indirectly_copyable_storable<_Iter, _Out>)
1172 constexpr unique_copy_result<_Iter, _Out>
1173 operator()(_Iter __first, _Sent __last, _Out __result,
1174 _Comp __comp = {}, _Proj __proj = {}) const
1175 {
1176 if (__first == __last)
1177 return {std::move(__first), std::move(__result)};
1178
1179 // TODO: perform a closer comparison with reference implementations
1180 if constexpr (forward_iterator<_Iter>)
1181 {
1182 auto __next = __first;
1183 *__result = *__next;
1184 while (++__next != __last)
1185 if (!std::__invoke(__comp,
1186 std::__invoke(__proj, *__first),
1187 std::__invoke(__proj, *__next)))
1188 {
1189 __first = __next;
1190 *++__result = *__first;
1191 }
1192 return {__next, std::move(++__result)};
1193 }
1194 else if constexpr (__detail::__can_reread_output<_Out, iter_value_t<_Iter>>)
1195 {
1196 *__result = *__first;
1197 while (++__first != __last)
1198 if (!std::__invoke(__comp,
1199 std::__invoke(__proj, *__result),
1200 std::__invoke(__proj, *__first)))
1201 *++__result = *__first;
1202 return {std::move(__first), std::move(++__result)};
1203 }
1204 else // indirectly_copyable_storable<_Iter, _Out>
1205 {
1206 auto __value = *__first;
1207 *__result = __value;
1208 while (++__first != __last)
1209 {
1210 if (!(bool)std::__invoke(__comp,
1211 std::__invoke(__proj, *__first),
1212 std::__invoke(__proj, __value)))
1213 {
1214 __value = *__first;
1215 *++__result = __value;
1216 }
1217 }
1218 return {std::move(__first), std::move(++__result)};
1219 }
1220 }
1221
1222 template<input_range _Range,
1223 weakly_incrementable _Out, typename _Proj = identity,
1224 indirect_equivalence_relation<
1225 projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
1226 requires indirectly_copyable<iterator_t<_Range>, _Out>
1227 && (forward_iterator<iterator_t<_Range>>
1228 || __detail::__can_reread_output<_Out, range_value_t<_Range>>
1229 || indirectly_copyable_storable<iterator_t<_Range>, _Out>)
1230 constexpr unique_copy_result<borrowed_iterator_t<_Range>, _Out>
1231 operator()(_Range&& __r, _Out __result,
1232 _Comp __comp = {}, _Proj __proj = {}) const
1233 {
1234 return (*this)(ranges::begin(__r), ranges::end(__r),
1235 std::move(__result),
1236 std::move(__comp), std::move(__proj));
1237 }
1238 };
1239
1240 inline constexpr __unique_copy_fn unique_copy{};
1241
1242 struct __reverse_fn
1243 {
1244 template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent>
1245 requires permutable<_Iter>
1246 constexpr _Iter
1247 operator()(_Iter __first, _Sent __last) const
1248 {
1249 auto __i = ranges::next(__first, __last);
1250 auto __tail = __i;
1251
1252 if constexpr (random_access_iterator<_Iter>)
1253 {
1254 if (__first != __last)
1255 {
1256 --__tail;
1257 while (__first < __tail)
1258 {
1259 ranges::iter_swap(__first, __tail);
1260 ++__first;
1261 --__tail;
1262 }
1263 }
1264 return __i;
1265 }
1266 else
1267 {
1268 for (;;)
1269 if (__first == __tail || __first == --__tail)
1270 break;
1271 else
1272 {
1273 ranges::iter_swap(__first, __tail);
1274 ++__first;
1275 }
1276 return __i;
1277 }
1278 }
1279
1280 template<bidirectional_range _Range>
1281 requires permutable<iterator_t<_Range>>
1282 constexpr borrowed_iterator_t<_Range>
1283 operator()(_Range&& __r) const
1284 {
1285 return (*this)(ranges::begin(__r), ranges::end(__r));
1286 }
1287 };
1288
1289 inline constexpr __reverse_fn reverse{};
1290
1291 template<typename _Iter, typename _Out>
1292 using reverse_copy_result = in_out_result<_Iter, _Out>;
1293
1294 struct __reverse_copy_fn
1295 {
1296 template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
1297 weakly_incrementable _Out>
1298 requires indirectly_copyable<_Iter, _Out>
1299 constexpr reverse_copy_result<_Iter, _Out>
1300 operator()(_Iter __first, _Sent __last, _Out __result) const
1301 {
1302 auto __i = ranges::next(__first, __last);
1303 auto __tail = __i;
1304 while (__first != __tail)
1305 {
1306 --__tail;
1307 *__result = *__tail;
1308 ++__result;
1309 }
1310 return {__i, std::move(__result)};
1311 }
1312
1313 template<bidirectional_range _Range, weakly_incrementable _Out>
1314 requires indirectly_copyable<iterator_t<_Range>, _Out>
1315 constexpr reverse_copy_result<borrowed_iterator_t<_Range>, _Out>
1316 operator()(_Range&& __r, _Out __result) const
1317 {
1318 return (*this)(ranges::begin(__r), ranges::end(__r),
1319 std::move(__result));
1320 }
1321 };
1322
1323 inline constexpr __reverse_copy_fn reverse_copy{};
1324
1325 struct __rotate_fn
1326 {
1327 template<permutable _Iter, sentinel_for<_Iter> _Sent>
1328 constexpr subrange<_Iter>
1329 operator()(_Iter __first, _Iter __middle, _Sent __last) const
1330 {
1331 auto __lasti = ranges::next(__first, __last);
1332 if (__first == __middle)
1333 return {__lasti, __lasti};
1334 if (__last == __middle)
1335 return {std::move(__first), std::move(__lasti)};
1336
1337 if constexpr (random_access_iterator<_Iter>)
1338 {
1339 auto __n = __lasti - __first;
1340 auto __k = __middle - __first;
1341
1342 if (__k == __n - __k)
1343 {
1344 ranges::swap_ranges(__first, __middle, __middle, __middle + __k);
1345 return {std::move(__middle), std::move(__lasti)};
1346 }
1347
1348 auto __p = __first;
1349 auto __ret = __first + (__lasti - __middle);
1350
1351 for (;;)
1352 {
1353 if (__k < __n - __k)
1354 {
1355 // TODO: is_pod is deprecated, but this condition is
1356 // consistent with the STL implementation.
1357 if constexpr (__is_pod(iter_value_t<_Iter>))
1358 if (__k == 1)
1359 {
1360 auto __t = std::move(*__p);
1361 ranges::move(__p + 1, __p + __n, __p);
1362 *(__p + __n - 1) = std::move(__t);
1363 return {std::move(__ret), std::move(__lasti)};
1364 }
1365 auto __q = __p + __k;
1366 for (decltype(__n) __i = 0; __i < __n - __k; ++ __i)
1367 {
1368 ranges::iter_swap(__p, __q);
1369 ++__p;
1370 ++__q;
1371 }
1372 __n %= __k;
1373 if (__n == 0)
1374 return {std::move(__ret), std::move(__lasti)};
1375 ranges::swap(__n, __k);
1376 __k = __n - __k;
1377 }
1378 else
1379 {
1380 __k = __n - __k;
1381 // TODO: is_pod is deprecated, but this condition is
1382 // consistent with the STL implementation.
1383 if constexpr (__is_pod(iter_value_t<_Iter>))
1384 if (__k == 1)
1385 {
1386 auto __t = std::move(*(__p + __n - 1));
1387 ranges::move_backward(__p, __p + __n - 1, __p + __n);
1388 *__p = std::move(__t);
1389 return {std::move(__ret), std::move(__lasti)};
1390 }
1391 auto __q = __p + __n;
1392 __p = __q - __k;
1393 for (decltype(__n) __i = 0; __i < __n - __k; ++ __i)
1394 {
1395 --__p;
1396 --__q;
1397 ranges::iter_swap(__p, __q);
1398 }
1399 __n %= __k;
1400 if (__n == 0)
1401 return {std::move(__ret), std::move(__lasti)};
1402 std::swap(__n, __k);
1403 }
1404 }
1405 }
1406 else if constexpr (bidirectional_iterator<_Iter>)
1407 {
1408 auto __tail = __lasti;
1409
1410 ranges::reverse(__first, __middle);
1411 ranges::reverse(__middle, __tail);
1412
1413 while (__first != __middle && __middle != __tail)
1414 {
1415 ranges::iter_swap(__first, --__tail);
1416 ++__first;
1417 }
1418
1419 if (__first == __middle)
1420 {
1421 ranges::reverse(__middle, __tail);
1422 return {std::move(__tail), std::move(__lasti)};
1423 }
1424 else
1425 {
1426 ranges::reverse(__first, __middle);
1427 return {std::move(__first), std::move(__lasti)};
1428 }
1429 }
1430 else
1431 {
1432 auto __first2 = __middle;
1433 do
1434 {
1435 ranges::iter_swap(__first, __first2);
1436 ++__first;
1437 ++__first2;
1438 if (__first == __middle)
1439 __middle = __first2;
1440 } while (__first2 != __last);
1441
1442 auto __ret = __first;
1443
1444 __first2 = __middle;
1445
1446 while (__first2 != __last)
1447 {
1448 ranges::iter_swap(__first, __first2);
1449 ++__first;
1450 ++__first2;
1451 if (__first == __middle)
1452 __middle = __first2;
1453 else if (__first2 == __last)
1454 __first2 = __middle;
1455 }
1456 return {std::move(__ret), std::move(__lasti)};
1457 }
1458 }
1459
1460 template<forward_range _Range>
1461 requires permutable<iterator_t<_Range>>
1462 constexpr borrowed_subrange_t<_Range>
1463 operator()(_Range&& __r, iterator_t<_Range> __middle) const
1464 {
1465 return (*this)(ranges::begin(__r), std::move(__middle),
1466 ranges::end(__r));
1467 }
1468 };
1469
1470 inline constexpr __rotate_fn rotate{};
1471
1472 template<typename _Iter, typename _Out>
1473 using rotate_copy_result = in_out_result<_Iter, _Out>;
1474
1475 struct __rotate_copy_fn
1476 {
1477 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
1478 weakly_incrementable _Out>
1479 requires indirectly_copyable<_Iter, _Out>
1480 constexpr rotate_copy_result<_Iter, _Out>
1481 operator()(_Iter __first, _Iter __middle, _Sent __last,
1482 _Out __result) const
1483 {
1484 auto __copy1 = ranges::copy(__middle,
1485 std::move(__last),
1486 std::move(__result));
1487 auto __copy2 = ranges::copy(std::move(__first),
1488 std::move(__middle),
1489 std::move(__copy1.out));
1490 return { std::move(__copy1.in), std::move(__copy2.out) };
1491 }
1492
1493 template<forward_range _Range, weakly_incrementable _Out>
1494 requires indirectly_copyable<iterator_t<_Range>, _Out>
1495 constexpr rotate_copy_result<borrowed_iterator_t<_Range>, _Out>
1496 operator()(_Range&& __r, iterator_t<_Range> __middle, _Out __result) const
1497 {
1498 return (*this)(ranges::begin(__r), std::move(__middle),
1499 ranges::end(__r), std::move(__result));
1500 }
1501 };
1502
1503 inline constexpr __rotate_copy_fn rotate_copy{};
1504
1505 struct __sample_fn
1506 {
1507 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1508 weakly_incrementable _Out, typename _Gen>
1509 requires (forward_iterator<_Iter> || random_access_iterator<_Out>)
1510 && indirectly_copyable<_Iter, _Out>
1511 && uniform_random_bit_generator<remove_reference_t<_Gen>>
1512 _Out
1513 operator()(_Iter __first, _Sent __last, _Out __out,
1514 iter_difference_t<_Iter> __n, _Gen&& __g) const
1515 {
1516 if constexpr (forward_iterator<_Iter>)
1517 {
1518 // FIXME: Forwarding to std::sample here requires computing __lasti
1519 // which may take linear time.
1520 auto __lasti = ranges::next(__first, __last);
1521 return _GLIBCXX_STD_A::
1522 sample(std::move(__first), std::move(__lasti), std::move(__out),
1523 __n, std::forward<_Gen>(__g));
1524 }
1525 else
1526 {
1527 using __distrib_type
1528 = uniform_int_distribution<iter_difference_t<_Iter>>;
1529 using __param_type = typename __distrib_type::param_type;
1530 __distrib_type __d{};
1531 iter_difference_t<_Iter> __sample_sz = 0;
1532 while (__first != __last && __sample_sz != __n)
1533 {
1534 __out[__sample_sz++] = *__first;
1535 ++__first;
1536 }
1537 for (auto __pop_sz = __sample_sz; __first != __last;
1538 ++__first, (void) ++__pop_sz)
1539 {
1540 const auto __k = __d(__g, __param_type{0, __pop_sz});
1541 if (__k < __n)
1542 __out[__k] = *__first;
1543 }
1544 return __out + __sample_sz;
1545 }
1546 }
1547
1548 template<input_range _Range, weakly_incrementable _Out, typename _Gen>
1549 requires (forward_range<_Range> || random_access_iterator<_Out>)
1550 && indirectly_copyable<iterator_t<_Range>, _Out>
1551 && uniform_random_bit_generator<remove_reference_t<_Gen>>
1552 _Out
1553 operator()(_Range&& __r, _Out __out,
1554 range_difference_t<_Range> __n, _Gen&& __g) const
1555 {
1556 return (*this)(ranges::begin(__r), ranges::end(__r),
1557 std::move(__out), __n,
1558 std::forward<_Gen>(__g));
1559 }
1560 };
1561
1562 inline constexpr __sample_fn sample{};
1563
1564#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1565 struct __shuffle_fn
1566 {
1567 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1568 typename _Gen>
1569 requires permutable<_Iter>
1570 && uniform_random_bit_generator<remove_reference_t<_Gen>>
1571 _Iter
1572 operator()(_Iter __first, _Sent __last, _Gen&& __g) const
1573 {
1574 auto __lasti = ranges::next(__first, __last);
1575 std::shuffle(std::move(__first), __lasti, std::forward<_Gen>(__g));
1576 return __lasti;
1577 }
1578
1579 template<random_access_range _Range, typename _Gen>
1580 requires permutable<iterator_t<_Range>>
1581 && uniform_random_bit_generator<remove_reference_t<_Gen>>
1582 borrowed_iterator_t<_Range>
1583 operator()(_Range&& __r, _Gen&& __g) const
1584 {
1585 return (*this)(ranges::begin(__r), ranges::end(__r),
1586 std::forward<_Gen>(__g));
1587 }
1588 };
1589
1590 inline constexpr __shuffle_fn shuffle{};
1591#endif
1592
1593 struct __push_heap_fn
1594 {
1595 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1596 typename _Comp = ranges::less, typename _Proj = identity>
1597 requires sortable<_Iter, _Comp, _Proj>
1598 constexpr _Iter
1599 operator()(_Iter __first, _Sent __last,
1600 _Comp __comp = {}, _Proj __proj = {}) const
1601 {
1602 auto __lasti = ranges::next(__first, __last);
1603 std::push_heap(__first, __lasti,
1604 __detail::__make_comp_proj(__comp, __proj));
1605 return __lasti;
1606 }
1607
1608 template<random_access_range _Range,
1609 typename _Comp = ranges::less, typename _Proj = identity>
1610 requires sortable<iterator_t<_Range>, _Comp, _Proj>
1611 constexpr borrowed_iterator_t<_Range>
1612 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1613 {
1614 return (*this)(ranges::begin(__r), ranges::end(__r),
1615 std::move(__comp), std::move(__proj));
1616 }
1617 };
1618
1619 inline constexpr __push_heap_fn push_heap{};
1620
1621 struct __pop_heap_fn
1622 {
1623 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1624 typename _Comp = ranges::less, typename _Proj = identity>
1625 requires sortable<_Iter, _Comp, _Proj>
1626 constexpr _Iter
1627 operator()(_Iter __first, _Sent __last,
1628 _Comp __comp = {}, _Proj __proj = {}) const
1629 {
1630 auto __lasti = ranges::next(__first, __last);
1631 std::pop_heap(__first, __lasti,
1632 __detail::__make_comp_proj(__comp, __proj));
1633 return __lasti;
1634 }
1635
1636 template<random_access_range _Range,
1637 typename _Comp = ranges::less, typename _Proj = identity>
1638 requires sortable<iterator_t<_Range>, _Comp, _Proj>
1639 constexpr borrowed_iterator_t<_Range>
1640 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1641 {
1642 return (*this)(ranges::begin(__r), ranges::end(__r),
1643 std::move(__comp), std::move(__proj));
1644 }
1645 };
1646
1647 inline constexpr __pop_heap_fn pop_heap{};
1648
1649 struct __make_heap_fn
1650 {
1651 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1652 typename _Comp = ranges::less, typename _Proj = identity>
1653 requires sortable<_Iter, _Comp, _Proj>
1654 constexpr _Iter
1655 operator()(_Iter __first, _Sent __last,
1656 _Comp __comp = {}, _Proj __proj = {}) const
1657 {
1658 auto __lasti = ranges::next(__first, __last);
1659 std::make_heap(__first, __lasti,
1660 __detail::__make_comp_proj(__comp, __proj));
1661 return __lasti;
1662 }
1663
1664 template<random_access_range _Range,
1665 typename _Comp = ranges::less, typename _Proj = identity>
1666 requires sortable<iterator_t<_Range>, _Comp, _Proj>
1667 constexpr borrowed_iterator_t<_Range>
1668 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1669 {
1670 return (*this)(ranges::begin(__r), ranges::end(__r),
1671 std::move(__comp), std::move(__proj));
1672 }
1673 };
1674
1675 inline constexpr __make_heap_fn make_heap{};
1676
1677 struct __sort_heap_fn
1678 {
1679 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1680 typename _Comp = ranges::less, typename _Proj = identity>
1681 requires sortable<_Iter, _Comp, _Proj>
1682 constexpr _Iter
1683 operator()(_Iter __first, _Sent __last,
1684 _Comp __comp = {}, _Proj __proj = {}) const
1685 {
1686 auto __lasti = ranges::next(__first, __last);
1687 std::sort_heap(__first, __lasti,
1688 __detail::__make_comp_proj(__comp, __proj));
1689 return __lasti;
1690 }
1691
1692 template<random_access_range _Range,
1693 typename _Comp = ranges::less, typename _Proj = identity>
1694 requires sortable<iterator_t<_Range>, _Comp, _Proj>
1695 constexpr borrowed_iterator_t<_Range>
1696 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1697 {
1698 return (*this)(ranges::begin(__r), ranges::end(__r),
1699 std::move(__comp), std::move(__proj));
1700 }
1701 };
1702
1703 inline constexpr __sort_heap_fn sort_heap{};
1704
1705 struct __is_heap_until_fn
1706 {
1707 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1708 typename _Proj = identity,
1709 indirect_strict_weak_order<projected<_Iter, _Proj>>
1710 _Comp = ranges::less>
1711 constexpr _Iter
1712 operator()(_Iter __first, _Sent __last,
1713 _Comp __comp = {}, _Proj __proj = {}) const
1714 {
1715 iter_difference_t<_Iter> __n = ranges::distance(__first, __last);
1716 iter_difference_t<_Iter> __parent = 0, __child = 1;
1717 for (; __child < __n; ++__child)
1718 if (std::__invoke(__comp,
1719 std::__invoke(__proj, *(__first + __parent)),
1720 std::__invoke(__proj, *(__first + __child))))
1721 return __first + __child;
1722 else if ((__child & 1) == 0)
1723 ++__parent;
1724
1725 return __first + __n;
1726 }
1727
1728 template<random_access_range _Range,
1729 typename _Proj = identity,
1730 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
1731 _Comp = ranges::less>
1732 constexpr borrowed_iterator_t<_Range>
1733 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1734 {
1735 return (*this)(ranges::begin(__r), ranges::end(__r),
1736 std::move(__comp), std::move(__proj));
1737 }
1738 };
1739
1740 inline constexpr __is_heap_until_fn is_heap_until{};
1741
1742 struct __is_heap_fn
1743 {
1744 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1745 typename _Proj = identity,
1746 indirect_strict_weak_order<projected<_Iter, _Proj>>
1747 _Comp = ranges::less>
1748 constexpr bool
1749 operator()(_Iter __first, _Sent __last,
1750 _Comp __comp = {}, _Proj __proj = {}) const
1751 {
1752 return (__last
1753 == ranges::is_heap_until(__first, __last,
1754 std::move(__comp),
1755 std::move(__proj)));
1756 }
1757
1758 template<random_access_range _Range,
1759 typename _Proj = identity,
1760 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
1761 _Comp = ranges::less>
1762 constexpr bool
1763 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1764 {
1765 return (*this)(ranges::begin(__r), ranges::end(__r),
1766 std::move(__comp), std::move(__proj));
1767 }
1768 };
1769
1770 inline constexpr __is_heap_fn is_heap{};
1771
1772 struct __sort_fn
1773 {
1774 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1775 typename _Comp = ranges::less, typename _Proj = identity>
1776 requires sortable<_Iter, _Comp, _Proj>
1777 constexpr _Iter
1778 operator()(_Iter __first, _Sent __last,
1779 _Comp __comp = {}, _Proj __proj = {}) const
1780 {
1781 auto __lasti = ranges::next(__first, __last);
1782 _GLIBCXX_STD_A::sort(std::move(__first), __lasti,
1783 __detail::__make_comp_proj(__comp, __proj));
1784 return __lasti;
1785 }
1786
1787 template<random_access_range _Range,
1788 typename _Comp = ranges::less, typename _Proj = identity>
1789 requires sortable<iterator_t<_Range>, _Comp, _Proj>
1790 constexpr borrowed_iterator_t<_Range>
1791 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1792 {
1793 return (*this)(ranges::begin(__r), ranges::end(__r),
1794 std::move(__comp), std::move(__proj));
1795 }
1796 };
1797
1798 inline constexpr __sort_fn sort{};
1799
1800 struct __stable_sort_fn
1801 {
1802 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1803 typename _Comp = ranges::less, typename _Proj = identity>
1804 requires sortable<_Iter, _Comp, _Proj>
1805 _Iter
1806 operator()(_Iter __first, _Sent __last,
1807 _Comp __comp = {}, _Proj __proj = {}) const
1808 {
1809 auto __lasti = ranges::next(__first, __last);
1810 std::stable_sort(std::move(__first), __lasti,
1811 __detail::__make_comp_proj(__comp, __proj));
1812 return __lasti;
1813 }
1814
1815 template<random_access_range _Range,
1816 typename _Comp = ranges::less, typename _Proj = identity>
1817 requires sortable<iterator_t<_Range>, _Comp, _Proj>
1818 borrowed_iterator_t<_Range>
1819 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1820 {
1821 return (*this)(ranges::begin(__r), ranges::end(__r),
1822 std::move(__comp), std::move(__proj));
1823 }
1824 };
1825
1826 inline constexpr __stable_sort_fn stable_sort{};
1827
1828 struct __partial_sort_fn
1829 {
1830 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1831 typename _Comp = ranges::less, typename _Proj = identity>
1832 requires sortable<_Iter, _Comp, _Proj>
1833 constexpr _Iter
1834 operator()(_Iter __first, _Iter __middle, _Sent __last,
1835 _Comp __comp = {}, _Proj __proj = {}) const
1836 {
1837 if (__first == __middle)
1838 return ranges::next(__first, __last);
1839
1840 ranges::make_heap(__first, __middle, __comp, __proj);
1841 auto __i = __middle;
1842 for (; __i != __last; ++__i)
1843 if (std::__invoke(__comp,
1844 std::__invoke(__proj, *__i),
1845 std::__invoke(__proj, *__first)))
1846 {
1847 ranges::pop_heap(__first, __middle, __comp, __proj);
1848 ranges::iter_swap(__middle-1, __i);
1849 ranges::push_heap(__first, __middle, __comp, __proj);
1850 }
1851 ranges::sort_heap(__first, __middle, __comp, __proj);
1852
1853 return __i;
1854 }
1855
1856 template<random_access_range _Range,
1857 typename _Comp = ranges::less, typename _Proj = identity>
1858 requires sortable<iterator_t<_Range>, _Comp, _Proj>
1859 constexpr borrowed_iterator_t<_Range>
1860 operator()(_Range&& __r, iterator_t<_Range> __middle,
1861 _Comp __comp = {}, _Proj __proj = {}) const
1862 {
1863 return (*this)(ranges::begin(__r), std::move(__middle),
1864 ranges::end(__r),
1865 std::move(__comp), std::move(__proj));
1866 }
1867 };
1868
1869 inline constexpr __partial_sort_fn partial_sort{};
1870
1871 template<typename _Iter, typename _Out>
1872 using partial_sort_copy_result = in_out_result<_Iter, _Out>;
1873
1874 struct __partial_sort_copy_fn
1875 {
1876 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
1877 random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
1878 typename _Comp = ranges::less,
1879 typename _Proj1 = identity, typename _Proj2 = identity>
1880 requires indirectly_copyable<_Iter1, _Iter2>
1881 && sortable<_Iter2, _Comp, _Proj2>
1882 && indirect_strict_weak_order<_Comp,
1883 projected<_Iter1, _Proj1>,
1884 projected<_Iter2, _Proj2>>
1885 constexpr partial_sort_copy_result<_Iter1, _Iter2>
1886 operator()(_Iter1 __first, _Sent1 __last,
1887 _Iter2 __result_first, _Sent2 __result_last,
1888 _Comp __comp = {},
1889 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
1890 {
1891 if (__result_first == __result_last)
1892 {
1893 // TODO: Eliminating the variable __lasti triggers an ICE.
1894 auto __lasti = ranges::next(std::move(__first),
1895 std::move(__last));
1896 return {std::move(__lasti), std::move(__result_first)};
1897 }
1898
1899 auto __result_real_last = __result_first;
1900 while (__first != __last && __result_real_last != __result_last)
1901 {
1902 *__result_real_last = *__first;
1903 ++__result_real_last;
1904 ++__first;
1905 }
1906
1907 ranges::make_heap(__result_first, __result_real_last, __comp, __proj2);
1908 for (; __first != __last; ++__first)
1909 if (std::__invoke(__comp,
1910 std::__invoke(__proj1, *__first),
1911 std::__invoke(__proj2, *__result_first)))
1912 {
1913 ranges::pop_heap(__result_first, __result_real_last,
1914 __comp, __proj2);
1915 *(__result_real_last-1) = *__first;
1916 ranges::push_heap(__result_first, __result_real_last,
1917 __comp, __proj2);
1918 }
1919 ranges::sort_heap(__result_first, __result_real_last, __comp, __proj2);
1920
1921 return {std::move(__first), std::move(__result_real_last)};
1922 }
1923
1924 template<input_range _Range1, random_access_range _Range2,
1925 typename _Comp = ranges::less,
1926 typename _Proj1 = identity, typename _Proj2 = identity>
1927 requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>>
1928 && sortable<iterator_t<_Range2>, _Comp, _Proj2>
1929 && indirect_strict_weak_order<_Comp,
1930 projected<iterator_t<_Range1>, _Proj1>,
1931 projected<iterator_t<_Range2>, _Proj2>>
1932 constexpr partial_sort_copy_result<borrowed_iterator_t<_Range1>,
1933 borrowed_iterator_t<_Range2>>
1934 operator()(_Range1&& __r, _Range2&& __out, _Comp __comp = {},
1935 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
1936 {
1937 return (*this)(ranges::begin(__r), ranges::end(__r),
1938 ranges::begin(__out), ranges::end(__out),
1939 std::move(__comp),
1940 std::move(__proj1), std::move(__proj2));
1941 }
1942 };
1943
1944 inline constexpr __partial_sort_copy_fn partial_sort_copy{};
1945
1946 struct __is_sorted_until_fn
1947 {
1948 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
1949 typename _Proj = identity,
1950 indirect_strict_weak_order<projected<_Iter, _Proj>>
1951 _Comp = ranges::less>
1952 constexpr _Iter
1953 operator()(_Iter __first, _Sent __last,
1954 _Comp __comp = {}, _Proj __proj = {}) const
1955 {
1956 if (__first == __last)
1957 return __first;
1958
1959 auto __next = __first;
1960 for (++__next; __next != __last; __first = __next, (void)++__next)
1961 if (std::__invoke(__comp,
1962 std::__invoke(__proj, *__next),
1963 std::__invoke(__proj, *__first)))
1964 return __next;
1965 return __next;
1966 }
1967
1968 template<forward_range _Range, typename _Proj = identity,
1969 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
1970 _Comp = ranges::less>
1971 constexpr borrowed_iterator_t<_Range>
1972 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1973 {
1974 return (*this)(ranges::begin(__r), ranges::end(__r),
1975 std::move(__comp), std::move(__proj));
1976 }
1977 };
1978
1979 inline constexpr __is_sorted_until_fn is_sorted_until{};
1980
1981 struct __is_sorted_fn
1982 {
1983 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
1984 typename _Proj = identity,
1985 indirect_strict_weak_order<projected<_Iter, _Proj>>
1986 _Comp = ranges::less>
1987 constexpr bool
1988 operator()(_Iter __first, _Sent __last,
1989 _Comp __comp = {}, _Proj __proj = {}) const
1990 {
1991 if (__first == __last)
1992 return true;
1993
1994 auto __next = __first;
1995 for (++__next; __next != __last; __first = __next, (void)++__next)
1996 if (std::__invoke(__comp,
1997 std::__invoke(__proj, *__next),
1998 std::__invoke(__proj, *__first)))
1999 return false;
2000 return true;
2001 }
2002
2003 template<forward_range _Range, typename _Proj = identity,
2004 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
2005 _Comp = ranges::less>
2006 constexpr bool
2007 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2008 {
2009 return (*this)(ranges::begin(__r), ranges::end(__r),
2010 std::move(__comp), std::move(__proj));
2011 }
2012 };
2013
2014 inline constexpr __is_sorted_fn is_sorted{};
2015
2016 struct __nth_element_fn
2017 {
2018 template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2019 typename _Comp = ranges::less, typename _Proj = identity>
2020 requires sortable<_Iter, _Comp, _Proj>
2021 constexpr _Iter
2022 operator()(_Iter __first, _Iter __nth, _Sent __last,
2023 _Comp __comp = {}, _Proj __proj = {}) const
2024 {
2025 auto __lasti = ranges::next(__first, __last);
2026 _GLIBCXX_STD_A::nth_element(std::move(__first), std::move(__nth),
2027 __lasti,
2028 __detail::__make_comp_proj(__comp, __proj));
2029 return __lasti;
2030 }
2031
2032 template<random_access_range _Range,
2033 typename _Comp = ranges::less, typename _Proj = identity>
2034 requires sortable<iterator_t<_Range>, _Comp, _Proj>
2035 constexpr borrowed_iterator_t<_Range>
2036 operator()(_Range&& __r, iterator_t<_Range> __nth,
2037 _Comp __comp = {}, _Proj __proj = {}) const
2038 {
2039 return (*this)(ranges::begin(__r), std::move(__nth),
2040 ranges::end(__r), std::move(__comp), std::move(__proj));
2041 }
2042 };
2043
2044 inline constexpr __nth_element_fn nth_element{};
2045
2046 struct __lower_bound_fn
2047 {
2048 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
2049 typename _Tp, typename _Proj = identity,
2050 indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
2051 _Comp = ranges::less>
2052 constexpr _Iter
2053 operator()(_Iter __first, _Sent __last,
2054 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
2055 {
2056 auto __len = ranges::distance(__first, __last);
2057
2058 while (__len > 0)
2059 {
2060 auto __half = __len / 2;
2061 auto __middle = __first;
2062 ranges::advance(__middle, __half);
2063 if (std::__invoke(__comp, std::__invoke(__proj, *__middle), __value))
2064 {
2065 __first = __middle;
2066 ++__first;
2067 __len = __len - __half - 1;
2068 }
2069 else
2070 __len = __half;
2071 }
2072 return __first;
2073 }
2074
2075 template<forward_range _Range, typename _Tp, typename _Proj = identity,
2076 indirect_strict_weak_order<const _Tp*,
2077 projected<iterator_t<_Range>, _Proj>>
2078 _Comp = ranges::less>
2079 constexpr borrowed_iterator_t<_Range>
2080 operator()(_Range&& __r,
2081 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
2082 {
2083 return (*this)(ranges::begin(__r), ranges::end(__r),
2084 __value, std::move(__comp), std::move(__proj));
2085 }
2086 };
2087
2088 inline constexpr __lower_bound_fn lower_bound{};
2089
2090 struct __upper_bound_fn
2091 {
2092 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
2093 typename _Tp, typename _Proj = identity,
2094 indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
2095 _Comp = ranges::less>
2096 constexpr _Iter
2097 operator()(_Iter __first, _Sent __last,
2098 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
2099 {
2100 auto __len = ranges::distance(__first, __last);
2101
2102 while (__len > 0)
2103 {
2104 auto __half = __len / 2;
2105 auto __middle = __first;
2106 ranges::advance(__middle, __half);
2107 if (std::__invoke(__comp, __value, std::__invoke(__proj, *__middle)))
2108 __len = __half;
2109 else
2110 {
2111 __first = __middle;
2112 ++__first;
2113 __len = __len - __half - 1;
2114 }
2115 }
2116 return __first;
2117 }
2118
2119 template<forward_range _Range, typename _Tp, typename _Proj = identity,
2120 indirect_strict_weak_order<const _Tp*,
2121 projected<iterator_t<_Range>, _Proj>>
2122 _Comp = ranges::less>
2123 constexpr borrowed_iterator_t<_Range>
2124 operator()(_Range&& __r,
2125 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
2126 {
2127 return (*this)(ranges::begin(__r), ranges::end(__r),
2128 __value, std::move(__comp), std::move(__proj));
2129 }
2130 };
2131
2132 inline constexpr __upper_bound_fn upper_bound{};
2133
2134 struct __equal_range_fn
2135 {
2136 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
2137 typename _Tp, typename _Proj = identity,
2138 indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
2139 _Comp = ranges::less>
2140 constexpr subrange<_Iter>
2141 operator()(_Iter __first, _Sent __last,
2142 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
2143 {
2144 auto __len = ranges::distance(__first, __last);
2145
2146 while (__len > 0)
2147 {
2148 auto __half = __len / 2;
2149 auto __middle = __first;
2150 ranges::advance(__middle, __half);
2151 if (std::__invoke(__comp,
2152 std::__invoke(__proj, *__middle),
2153 __value))
2154 {
2155 __first = __middle;
2156 ++__first;
2157 __len = __len - __half - 1;
2158 }
2159 else if (std::__invoke(__comp,
2160 __value,
2161 std::__invoke(__proj, *__middle)))
2162 __len = __half;
2163 else
2164 {
2165 auto __left
2166 = ranges::lower_bound(__first, __middle,
2167 __value, __comp, __proj);
2168 ranges::advance(__first, __len);
2169 auto __right
2170 = ranges::upper_bound(++__middle, __first,
2171 __value, __comp, __proj);
2172 return {__left, __right};
2173 }
2174 }
2175 return {__first, __first};
2176 }
2177
2178 template<forward_range _Range,
2179 typename _Tp, typename _Proj = identity,
2180 indirect_strict_weak_order<const _Tp*,
2181 projected<iterator_t<_Range>, _Proj>>
2182 _Comp = ranges::less>
2183 constexpr borrowed_subrange_t<_Range>
2184 operator()(_Range&& __r, const _Tp& __value,
2185 _Comp __comp = {}, _Proj __proj = {}) const
2186 {
2187 return (*this)(ranges::begin(__r), ranges::end(__r),
2188 __value, std::move(__comp), std::move(__proj));
2189 }
2190 };
2191
2192 inline constexpr __equal_range_fn equal_range{};
2193
2194 struct __binary_search_fn
2195 {
2196 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
2197 typename _Tp, typename _Proj = identity,
2198 indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
2199 _Comp = ranges::less>
2200 constexpr bool
2201 operator()(_Iter __first, _Sent __last,
2202 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
2203 {
2204 auto __i = ranges::lower_bound(__first, __last, __value, __comp, __proj);
2205 if (__i == __last)
2206 return false;
2207 return !(bool)std::__invoke(__comp, __value,
2208 std::__invoke(__proj, *__i));
2209 }
2210
2211 template<forward_range _Range,
2212 typename _Tp, typename _Proj = identity,
2213 indirect_strict_weak_order<const _Tp*,
2214 projected<iterator_t<_Range>, _Proj>>
2215 _Comp = ranges::less>
2216 constexpr bool
2217 operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {},
2218 _Proj __proj = {}) const
2219 {
2220 return (*this)(ranges::begin(__r), ranges::end(__r),
2221 __value, std::move(__comp), std::move(__proj));
2222 }
2223 };
2224
2225 inline constexpr __binary_search_fn binary_search{};
2226
2227 struct __is_partitioned_fn
2228 {
2229 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
2230 typename _Proj = identity,
2231 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
2232 constexpr bool
2233 operator()(_Iter __first, _Sent __last,
2234 _Pred __pred, _Proj __proj = {}) const
2235 {
2236 __first = ranges::find_if_not(std::move(__first), __last,
2237 __pred, __proj);
2238 if (__first == __last)
2239 return true;
2240 ++__first;
2241 return ranges::none_of(std::move(__first), std::move(__last),
2242 std::move(__pred), std::move(__proj));
2243 }
2244
2245 template<input_range _Range, typename _Proj = identity,
2246 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
2247 _Pred>
2248 constexpr bool
2249 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
2250 {
2251 return (*this)(ranges::begin(__r), ranges::end(__r),
2252 std::move(__pred), std::move(__proj));
2253 }
2254 };
2255
2256 inline constexpr __is_partitioned_fn is_partitioned{};
2257
2258 struct __partition_fn
2259 {
2260 template<permutable _Iter, sentinel_for<_Iter> _Sent,
2261 typename _Proj = identity,
2262 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
2263 constexpr subrange<_Iter>
2264 operator()(_Iter __first, _Sent __last,
2265 _Pred __pred, _Proj __proj = {}) const
2266 {
2267 if constexpr (bidirectional_iterator<_Iter>)
2268 {
2269 auto __lasti = ranges::next(__first, __last);
2270 auto __tail = __lasti;
2271 for (;;)
2272 {
2273 for (;;)
2274 if (__first == __tail)
2275 return {std::move(__first), std::move(__lasti)};
2276 else if (std::__invoke(__pred,
2277 std::__invoke(__proj, *__first)))
2278 ++__first;
2279 else
2280 break;
2281 --__tail;
2282 for (;;)
2283 if (__first == __tail)
2284 return {std::move(__first), std::move(__lasti)};
2285 else if (!(bool)std::__invoke(__pred,
2286 std::__invoke(__proj, *__tail)))
2287 --__tail;
2288 else
2289 break;
2290 ranges::iter_swap(__first, __tail);
2291 ++__first;
2292 }
2293 }
2294 else
2295 {
2296 if (__first == __last)
2297 return {__first, __first};
2298
2299 while (std::__invoke(__pred, std::__invoke(__proj, *__first)))
2300 if (++__first == __last)
2301 return {__first, __first};
2302
2303 auto __next = __first;
2304 while (++__next != __last)
2305 if (std::__invoke(__pred, std::__invoke(__proj, *__next)))
2306 {
2307 ranges::iter_swap(__first, __next);
2308 ++__first;
2309 }
2310
2311 return {std::move(__first), std::move(__next)};
2312 }
2313 }
2314
2315 template<forward_range _Range, typename _Proj = identity,
2316 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
2317 _Pred>
2318 requires permutable<iterator_t<_Range>>
2319 constexpr borrowed_subrange_t<_Range>
2320 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
2321 {
2322 return (*this)(ranges::begin(__r), ranges::end(__r),
2323 std::move(__pred), std::move(__proj));
2324 }
2325 };
2326
2327 inline constexpr __partition_fn partition{};
2328
2329#if _GLIBCXX_HOSTED
2330 struct __stable_partition_fn
2331 {
2332 template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
2333 typename _Proj = identity,
2334 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
2335 requires permutable<_Iter>
2336 subrange<_Iter>
2337 operator()(_Iter __first, _Sent __last,
2338 _Pred __pred, _Proj __proj = {}) const
2339 {
2340 auto __lasti = ranges::next(__first, __last);
2341 auto __middle
2342 = std::stable_partition(std::move(__first), __lasti,
2343 __detail::__make_pred_proj(__pred, __proj));
2344 return {std::move(__middle), std::move(__lasti)};
2345 }
2346
2347 template<bidirectional_range _Range, typename _Proj = identity,
2348 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
2349 _Pred>
2350 requires permutable<iterator_t<_Range>>
2351 borrowed_subrange_t<_Range>
2352 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
2353 {
2354 return (*this)(ranges::begin(__r), ranges::end(__r),
2355 std::move(__pred), std::move(__proj));
2356 }
2357 };
2358
2359 inline constexpr __stable_partition_fn stable_partition{};
2360#endif
2361
2362 template<typename _Iter, typename _Out1, typename _Out2>
2363 struct in_out_out_result
2364 {
2365 [[no_unique_address]] _Iter in;
2366 [[no_unique_address]] _Out1 out1;
2367 [[no_unique_address]] _Out2 out2;
2368
2369 template<typename _IIter, typename _OOut1, typename _OOut2>
2370 requires convertible_to<const _Iter&, _IIter>
2371 && convertible_to<const _Out1&, _OOut1>
2372 && convertible_to<const _Out2&, _OOut2>
2373 constexpr
2374 operator in_out_out_result<_IIter, _OOut1, _OOut2>() const &
2375 { return {in, out1, out2}; }
2376
2377 template<typename _IIter, typename _OOut1, typename _OOut2>
2378 requires convertible_to<_Iter, _IIter>
2379 && convertible_to<_Out1, _OOut1>
2380 && convertible_to<_Out2, _OOut2>
2381 constexpr
2382 operator in_out_out_result<_IIter, _OOut1, _OOut2>() &&
2383 { return {std::move(in), std::move(out1), std::move(out2)}; }
2384 };
2385
2386 template<typename _Iter, typename _Out1, typename _Out2>
2387 using partition_copy_result = in_out_out_result<_Iter, _Out1, _Out2>;
2388
2389 struct __partition_copy_fn
2390 {
2391 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
2392 weakly_incrementable _Out1, weakly_incrementable _Out2,
2393 typename _Proj = identity,
2394 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
2395 requires indirectly_copyable<_Iter, _Out1>
2396 && indirectly_copyable<_Iter, _Out2>
2397 constexpr partition_copy_result<_Iter, _Out1, _Out2>
2398 operator()(_Iter __first, _Sent __last,
2399 _Out1 __out_true, _Out2 __out_false,
2400 _Pred __pred, _Proj __proj = {}) const
2401 {
2402 for (; __first != __last; ++__first)
2403 if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
2404 {
2405 *__out_true = *__first;
2406 ++__out_true;
2407 }
2408 else
2409 {
2410 *__out_false = *__first;
2411 ++__out_false;
2412 }
2413
2414 return {std::move(__first),
2415 std::move(__out_true), std::move(__out_false)};
2416 }
2417
2418 template<input_range _Range, weakly_incrementable _Out1,
2419 weakly_incrementable _Out2,
2420 typename _Proj = identity,
2421 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
2422 _Pred>
2423 requires indirectly_copyable<iterator_t<_Range>, _Out1>
2424 && indirectly_copyable<iterator_t<_Range>, _Out2>
2425 constexpr partition_copy_result<borrowed_iterator_t<_Range>, _Out1, _Out2>
2426 operator()(_Range&& __r, _Out1 __out_true, _Out2 __out_false,
2427 _Pred __pred, _Proj __proj = {}) const
2428 {
2429 return (*this)(ranges::begin(__r), ranges::end(__r),
2430 std::move(__out_true), std::move(__out_false),
2431 std::move(__pred), std::move(__proj));
2432 }
2433 };
2434
2435 inline constexpr __partition_copy_fn partition_copy{};
2436
2437 struct __partition_point_fn
2438 {
2439 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
2440 typename _Proj = identity,
2441 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
2442 constexpr _Iter
2443 operator()(_Iter __first, _Sent __last,
2444 _Pred __pred, _Proj __proj = {}) const
2445 {
2446 auto __len = ranges::distance(__first, __last);
2447
2448 while (__len > 0)
2449 {
2450 auto __half = __len / 2;
2451 auto __middle = __first;
2452 ranges::advance(__middle, __half);
2453 if (std::__invoke(__pred, std::__invoke(__proj, *__middle)))
2454 {
2455 __first = __middle;
2456 ++__first;
2457 __len = __len - __half - 1;
2458 }
2459 else
2460 __len = __half;
2461 }
2462 return __first;
2463 }
2464
2465 template<forward_range _Range, typename _Proj = identity,
2466 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
2467 _Pred>
2468 constexpr borrowed_iterator_t<_Range>
2469 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
2470 {
2471 return (*this)(ranges::begin(__r), ranges::end(__r),
2472 std::move(__pred), std::move(__proj));
2473 }
2474 };
2475
2476 inline constexpr __partition_point_fn partition_point{};
2477
2478 template<typename _Iter1, typename _Iter2, typename _Out>
2479 using merge_result = in_in_out_result<_Iter1, _Iter2, _Out>;
2480
2481 struct __merge_fn
2482 {
2483 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
2484 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
2485 weakly_incrementable _Out, typename _Comp = ranges::less,
2486 typename _Proj1 = identity, typename _Proj2 = identity>
2487 requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
2488 constexpr merge_result<_Iter1, _Iter2, _Out>
2489 operator()(_Iter1 __first1, _Sent1 __last1,
2490 _Iter2 __first2, _Sent2 __last2, _Out __result,
2491 _Comp __comp = {},
2492 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2493 {
2494 while (__first1 != __last1 && __first2 != __last2)
2495 {
2496 if (std::__invoke(__comp,
2497 std::__invoke(__proj2, *__first2),
2498 std::__invoke(__proj1, *__first1)))
2499 {
2500 *__result = *__first2;
2501 ++__first2;
2502 }
2503 else
2504 {
2505 *__result = *__first1;
2506 ++__first1;
2507 }
2508 ++__result;
2509 }
2510 auto __copy1 = ranges::copy(std::move(__first1), std::move(__last1),
2511 std::move(__result));
2512 auto __copy2 = ranges::copy(std::move(__first2), std::move(__last2),
2513 std::move(__copy1.out));
2514 return { std::move(__copy1.in), std::move(__copy2.in),
2515 std::move(__copy2.out) };
2516 }
2517
2518 template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
2519 typename _Comp = ranges::less,
2520 typename _Proj1 = identity, typename _Proj2 = identity>
2521 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
2522 _Comp, _Proj1, _Proj2>
2523 constexpr merge_result<borrowed_iterator_t<_Range1>,
2524 borrowed_iterator_t<_Range2>,
2525 _Out>
2526 operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
2527 _Comp __comp = {},
2528 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2529 {
2530 return (*this)(ranges::begin(__r1), ranges::end(__r1),
2531 ranges::begin(__r2), ranges::end(__r2),
2532 std::move(__result), std::move(__comp),
2533 std::move(__proj1), std::move(__proj2));
2534 }
2535 };
2536
2537 inline constexpr __merge_fn merge{};
2538
2539 struct __inplace_merge_fn
2540 {
2541 template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
2542 typename _Comp = ranges::less,
2543 typename _Proj = identity>
2544 requires sortable<_Iter, _Comp, _Proj>
2545 _Iter
2546 operator()(_Iter __first, _Iter __middle, _Sent __last,
2547 _Comp __comp = {}, _Proj __proj = {}) const
2548 {
2549 auto __lasti = ranges::next(__first, __last);
2550 std::inplace_merge(std::move(__first), std::move(__middle), __lasti,
2551 __detail::__make_comp_proj(__comp, __proj));
2552 return __lasti;
2553 }
2554
2555 template<bidirectional_range _Range,
2556 typename _Comp = ranges::less, typename _Proj = identity>
2557 requires sortable<iterator_t<_Range>, _Comp, _Proj>
2558 borrowed_iterator_t<_Range>
2559 operator()(_Range&& __r, iterator_t<_Range> __middle,
2560 _Comp __comp = {}, _Proj __proj = {}) const
2561 {
2562 return (*this)(ranges::begin(__r), std::move(__middle),
2563 ranges::end(__r),
2564 std::move(__comp), std::move(__proj));
2565 }
2566 };
2567
2568 inline constexpr __inplace_merge_fn inplace_merge{};
2569
2570 struct __includes_fn
2571 {
2572 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
2573 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
2574 typename _Proj1 = identity, typename _Proj2 = identity,
2575 indirect_strict_weak_order<projected<_Iter1, _Proj1>,
2576 projected<_Iter2, _Proj2>>
2577 _Comp = ranges::less>
2578 constexpr bool
2579 operator()(_Iter1 __first1, _Sent1 __last1,
2580 _Iter2 __first2, _Sent2 __last2,
2581 _Comp __comp = {},
2582 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2583 {
2584 while (__first1 != __last1 && __first2 != __last2)
2585 if (std::__invoke(__comp,
2586 std::__invoke(__proj2, *__first2),
2587 std::__invoke(__proj1, *__first1)))
2588 return false;
2589 else if (std::__invoke(__comp,
2590 std::__invoke(__proj1, *__first1),
2591 std::__invoke(__proj2, *__first2)))
2592 ++__first1;
2593 else
2594 {
2595 ++__first1;
2596 ++__first2;
2597 }
2598
2599 return __first2 == __last2;
2600 }
2601
2602 template<input_range _Range1, input_range _Range2,
2603 typename _Proj1 = identity, typename _Proj2 = identity,
2604 indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
2605 projected<iterator_t<_Range2>, _Proj2>>
2606 _Comp = ranges::less>
2607 constexpr bool
2608 operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {},
2609 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2610 {
2611 return (*this)(ranges::begin(__r1), ranges::end(__r1),
2612 ranges::begin(__r2), ranges::end(__r2),
2613 std::move(__comp),
2614 std::move(__proj1), std::move(__proj2));
2615 }
2616 };
2617
2618 inline constexpr __includes_fn includes{};
2619
2620 template<typename _Iter1, typename _Iter2, typename _Out>
2621 using set_union_result = in_in_out_result<_Iter1, _Iter2, _Out>;
2622
2623 struct __set_union_fn
2624 {
2625 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
2626 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
2627 weakly_incrementable _Out, typename _Comp = ranges::less,
2628 typename _Proj1 = identity, typename _Proj2 = identity>
2629 requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
2630 constexpr set_union_result<_Iter1, _Iter2, _Out>
2631 operator()(_Iter1 __first1, _Sent1 __last1,
2632 _Iter2 __first2, _Sent2 __last2,
2633 _Out __result, _Comp __comp = {},
2634 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2635 {
2636 while (__first1 != __last1 && __first2 != __last2)
2637 {
2638 if (std::__invoke(__comp,
2639 std::__invoke(__proj1, *__first1),
2640 std::__invoke(__proj2, *__first2)))
2641 {
2642 *__result = *__first1;
2643 ++__first1;
2644 }
2645 else if (std::__invoke(__comp,
2646 std::__invoke(__proj2, *__first2),
2647 std::__invoke(__proj1, *__first1)))
2648 {
2649 *__result = *__first2;
2650 ++__first2;
2651 }
2652 else
2653 {
2654 *__result = *__first1;
2655 ++__first1;
2656 ++__first2;
2657 }
2658 ++__result;
2659 }
2660 auto __copy1 = ranges::copy(std::move(__first1), std::move(__last1),
2661 std::move(__result));
2662 auto __copy2 = ranges::copy(std::move(__first2), std::move(__last2),
2663 std::move(__copy1.out));
2664 return {std::move(__copy1.in), std::move(__copy2.in),
2665 std::move(__copy2.out)};
2666 }
2667
2668 template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
2669 typename _Comp = ranges::less,
2670 typename _Proj1 = identity, typename _Proj2 = identity>
2671 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
2672 _Comp, _Proj1, _Proj2>
2673 constexpr set_union_result<borrowed_iterator_t<_Range1>,
2674 borrowed_iterator_t<_Range2>, _Out>
2675 operator()(_Range1&& __r1, _Range2&& __r2,
2676 _Out __result, _Comp __comp = {},
2677 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2678 {
2679 return (*this)(ranges::begin(__r1), ranges::end(__r1),
2680 ranges::begin(__r2), ranges::end(__r2),
2681 std::move(__result), std::move(__comp),
2682 std::move(__proj1), std::move(__proj2));
2683 }
2684 };
2685
2686 inline constexpr __set_union_fn set_union{};
2687
2688 template<typename _Iter1, typename _Iter2, typename _Out>
2689 using set_intersection_result = in_in_out_result<_Iter1, _Iter2, _Out>;
2690
2691 struct __set_intersection_fn
2692 {
2693 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
2694 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
2695 weakly_incrementable _Out, typename _Comp = ranges::less,
2696 typename _Proj1 = identity, typename _Proj2 = identity>
2697 requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
2698 constexpr set_intersection_result<_Iter1, _Iter2, _Out>
2699 operator()(_Iter1 __first1, _Sent1 __last1,
2700 _Iter2 __first2, _Sent2 __last2, _Out __result,
2701 _Comp __comp = {},
2702 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2703 {
2704 while (__first1 != __last1 && __first2 != __last2)
2705 if (std::__invoke(__comp,
2706 std::__invoke(__proj1, *__first1),
2707 std::__invoke(__proj2, *__first2)))
2708 ++__first1;
2709 else if (std::__invoke(__comp,
2710 std::__invoke(__proj2, *__first2),
2711 std::__invoke(__proj1, *__first1)))
2712 ++__first2;
2713 else
2714 {
2715 *__result = *__first1;
2716 ++__first1;
2717 ++__first2;
2718 ++__result;
2719 }
2720 // TODO: Eliminating these variables triggers an ICE.
2721 auto __last1i = ranges::next(std::move(__first1), std::move(__last1));
2722 auto __last2i = ranges::next(std::move(__first2), std::move(__last2));
2723 return {std::move(__last1i), std::move(__last2i), std::move(__result)};
2724 }
2725
2726 template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
2727 typename _Comp = ranges::less,
2728 typename _Proj1 = identity, typename _Proj2 = identity>
2729 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
2730 _Comp, _Proj1, _Proj2>
2731 constexpr set_intersection_result<borrowed_iterator_t<_Range1>,
2732 borrowed_iterator_t<_Range2>, _Out>
2733 operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
2734 _Comp __comp = {},
2735 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2736 {
2737 return (*this)(ranges::begin(__r1), ranges::end(__r1),
2738 ranges::begin(__r2), ranges::end(__r2),
2739 std::move(__result), std::move(__comp),
2740 std::move(__proj1), std::move(__proj2));
2741 }
2742 };
2743
2744 inline constexpr __set_intersection_fn set_intersection{};
2745
2746 template<typename _Iter, typename _Out>
2747 using set_difference_result = in_out_result<_Iter, _Out>;
2748
2749 struct __set_difference_fn
2750 {
2751 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
2752 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
2753 weakly_incrementable _Out, typename _Comp = ranges::less,
2754 typename _Proj1 = identity, typename _Proj2 = identity>
2755 requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
2756 constexpr set_difference_result<_Iter1, _Out>
2757 operator()(_Iter1 __first1, _Sent1 __last1,
2758 _Iter2 __first2, _Sent2 __last2, _Out __result,
2759 _Comp __comp = {},
2760 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2761 {
2762 while (__first1 != __last1 && __first2 != __last2)
2763 if (std::__invoke(__comp,
2764 std::__invoke(__proj1, *__first1),
2765 std::__invoke(__proj2, *__first2)))
2766 {
2767 *__result = *__first1;
2768 ++__first1;
2769 ++__result;
2770 }
2771 else if (std::__invoke(__comp,
2772 std::__invoke(__proj2, *__first2),
2773 std::__invoke(__proj1, *__first1)))
2774 ++__first2;
2775 else
2776 {
2777 ++__first1;
2778 ++__first2;
2779 }
2780 return ranges::copy(std::move(__first1), std::move(__last1),
2781 std::move(__result));
2782 }
2783
2784 template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
2785 typename _Comp = ranges::less,
2786 typename _Proj1 = identity, typename _Proj2 = identity>
2787 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
2788 _Comp, _Proj1, _Proj2>
2789 constexpr set_difference_result<borrowed_iterator_t<_Range1>, _Out>
2790 operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
2791 _Comp __comp = {},
2792 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2793 {
2794 return (*this)(ranges::begin(__r1), ranges::end(__r1),
2795 ranges::begin(__r2), ranges::end(__r2),
2796 std::move(__result), std::move(__comp),
2797 std::move(__proj1), std::move(__proj2));
2798 }
2799 };
2800
2801 inline constexpr __set_difference_fn set_difference{};
2802
2803 template<typename _Iter1, typename _Iter2, typename _Out>
2804 using set_symmetric_difference_result
2805 = in_in_out_result<_Iter1, _Iter2, _Out>;
2806
2807 struct __set_symmetric_difference_fn
2808 {
2809 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
2810 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
2811 weakly_incrementable _Out, typename _Comp = ranges::less,
2812 typename _Proj1 = identity, typename _Proj2 = identity>
2813 requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
2814 constexpr set_symmetric_difference_result<_Iter1, _Iter2, _Out>
2815 operator()(_Iter1 __first1, _Sent1 __last1,
2816 _Iter2 __first2, _Sent2 __last2,
2817 _Out __result, _Comp __comp = {},
2818 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2819 {
2820 while (__first1 != __last1 && __first2 != __last2)
2821 if (std::__invoke(__comp,
2822 std::__invoke(__proj1, *__first1),
2823 std::__invoke(__proj2, *__first2)))
2824 {
2825 *__result = *__first1;
2826 ++__first1;
2827 ++__result;
2828 }
2829 else if (std::__invoke(__comp,
2830 std::__invoke(__proj2, *__first2),
2831 std::__invoke(__proj1, *__first1)))
2832 {
2833 *__result = *__first2;
2834 ++__first2;
2835 ++__result;
2836 }
2837 else
2838 {
2839 ++__first1;
2840 ++__first2;
2841 }
2842 auto __copy1 = ranges::copy(std::move(__first1), std::move(__last1),
2843 std::move(__result));
2844 auto __copy2 = ranges::copy(std::move(__first2), std::move(__last2),
2845 std::move(__copy1.out));
2846 return {std::move(__copy1.in), std::move(__copy2.in),
2847 std::move(__copy2.out)};
2848 }
2849
2850 template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
2851 typename _Comp = ranges::less,
2852 typename _Proj1 = identity, typename _Proj2 = identity>
2853 requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
2854 _Comp, _Proj1, _Proj2>
2855 constexpr set_symmetric_difference_result<borrowed_iterator_t<_Range1>,
2856 borrowed_iterator_t<_Range2>,
2857 _Out>
2858 operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
2859 _Comp __comp = {},
2860 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2861 {
2862 return (*this)(ranges::begin(__r1), ranges::end(__r1),
2863 ranges::begin(__r2), ranges::end(__r2),
2864 std::move(__result), std::move(__comp),
2865 std::move(__proj1), std::move(__proj2));
2866 }
2867 };
2868
2869 inline constexpr __set_symmetric_difference_fn set_symmetric_difference{};
2870
2871 // min is defined in <bits/ranges_util.h>.
2872
2873 struct __max_fn
2874 {
2875 template<typename _Tp, typename _Proj = identity,
2876 indirect_strict_weak_order<projected<const _Tp*, _Proj>>
2877 _Comp = ranges::less>
2878 constexpr const _Tp&
2879 operator()(const _Tp& __a, const _Tp& __b,
2880 _Comp __comp = {}, _Proj __proj = {}) const
2881 {
2882 if (std::__invoke(__comp,
2883 std::__invoke(__proj, __a),
2884 std::__invoke(__proj, __b)))
2885 return __b;
2886 else
2887 return __a;
2888 }
2889
2890 template<input_range _Range, typename _Proj = identity,
2891 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
2892 _Comp = ranges::less>
2893 requires indirectly_copyable_storable<iterator_t<_Range>,
2894 range_value_t<_Range>*>
2895 constexpr range_value_t<_Range>
2896 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2897 {
2898 auto __first = ranges::begin(__r);
2899 auto __last = ranges::end(__r);
2900 __glibcxx_assert(__first != __last);
2901 auto __result = *__first;
2902 while (++__first != __last)
2903 {
2904 auto __tmp = *__first;
2905 if (std::__invoke(__comp,
2906 std::__invoke(__proj, __result),
2907 std::__invoke(__proj, __tmp)))
2908 __result = std::move(__tmp);
2909 }
2910 return __result;
2911 }
2912
2913 template<copyable _Tp, typename _Proj = identity,
2914 indirect_strict_weak_order<projected<const _Tp*, _Proj>>
2915 _Comp = ranges::less>
2916 constexpr _Tp
2917 operator()(initializer_list<_Tp> __r,
2918 _Comp __comp = {}, _Proj __proj = {}) const
2919 {
2920 return (*this)(ranges::subrange(__r),
2921 std::move(__comp), std::move(__proj));
2922 }
2923 };
2924
2925 inline constexpr __max_fn max{};
2926
2927 struct __clamp_fn
2928 {
2929 template<typename _Tp, typename _Proj = identity,
2930 indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp
2931 = ranges::less>
2932 constexpr const _Tp&
2933 operator()(const _Tp& __val, const _Tp& __lo, const _Tp& __hi,
2934 _Comp __comp = {}, _Proj __proj = {}) const
2935 {
2936 __glibcxx_assert(!(std::__invoke(__comp,
2937 std::__invoke(__proj, __hi),
2938 std::__invoke(__proj, __lo))));
2939 auto&& __proj_val = std::__invoke(__proj, __val);
2940 if (std::__invoke(__comp, __proj_val, std::__invoke(__proj, __lo)))
2941 return __lo;
2942 else if (std::__invoke(__comp, std::__invoke(__proj, __hi), __proj_val))
2943 return __hi;
2944 else
2945 return __val;
2946 }
2947 };
2948
2949 inline constexpr __clamp_fn clamp{};
2950
2951 template<typename _Tp>
2952 struct min_max_result
2953 {
2954 [[no_unique_address]] _Tp min;
2955 [[no_unique_address]] _Tp max;
2956
2957 template<typename _Tp2>
2958 requires convertible_to<const _Tp&, _Tp2>
2959 constexpr
2960 operator min_max_result<_Tp2>() const &
2961 { return {min, max}; }
2962
2963 template<typename _Tp2>
2964 requires convertible_to<_Tp, _Tp2>
2965 constexpr
2966 operator min_max_result<_Tp2>() &&
2967 { return {std::move(min), std::move(max)}; }
2968 };
2969
2970 template<typename _Tp>
2971 using minmax_result = min_max_result<_Tp>;
2972
2973 struct __minmax_fn
2974 {
2975 template<typename _Tp, typename _Proj = identity,
2976 indirect_strict_weak_order<projected<const _Tp*, _Proj>>
2977 _Comp = ranges::less>
2978 constexpr minmax_result<const _Tp&>
2979 operator()(const _Tp& __a, const _Tp& __b,
2980 _Comp __comp = {}, _Proj __proj = {}) const
2981 {
2982 if (std::__invoke(__comp,
2983 std::__invoke(__proj, __b),
2984 std::__invoke(__proj, __a)))
2985 return {__b, __a};
2986 else
2987 return {__a, __b};
2988 }
2989
2990 template<input_range _Range, typename _Proj = identity,
2991 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
2992 _Comp = ranges::less>
2993 requires indirectly_copyable_storable<iterator_t<_Range>, range_value_t<_Range>*>
2994 constexpr minmax_result<range_value_t<_Range>>
2995 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2996 {
2997 auto __first = ranges::begin(__r);
2998 auto __last = ranges::end(__r);
2999 __glibcxx_assert(__first != __last);
3000 auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
3001 minmax_result<range_value_t<_Range>> __result = {*__first, __result.min};
3002 if (++__first == __last)
3003 return __result;
3004 else
3005 {
3006 // At this point __result.min == __result.max, so a single
3007 // comparison with the next element suffices.
3008 auto&& __val = *__first;
3009 if (__comp_proj(__val, __result.min))
3010 __result.min = std::forward<decltype(__val)>(__val);
3011 else
3012 __result.max = std::forward<decltype(__val)>(__val);
3013 }
3014 while (++__first != __last)
3015 {
3016 // Now process two elements at a time so that we perform at most
3017 // 1 + 3*(N-2)/2 comparisons in total (each of the (N-2)/2
3018 // iterations of this loop performs three comparisons).
3019 range_value_t<_Range> __val1 = *__first;
3020 if (++__first == __last)
3021 {
3022 // N is odd; in this final iteration, we perform at most two
3023 // comparisons, for a total of 1 + 3*(N-3)/2 + 2 comparisons,
3024 // which is not more than 3*N/2, as required.
3025 if (__comp_proj(__val1, __result.min))
3026 __result.min = std::move(__val1);
3027 else if (!__comp_proj(__val1, __result.max))
3028 __result.max = std::move(__val1);
3029 break;
3030 }
3031 auto&& __val2 = *__first;
3032 if (!__comp_proj(__val2, __val1))
3033 {
3034 if (__comp_proj(__val1, __result.min))
3035 __result.min = std::move(__val1);
3036 if (!__comp_proj(__val2, __result.max))
3037 __result.max = std::forward<decltype(__val2)>(__val2);
3038 }
3039 else
3040 {
3041 if (__comp_proj(__val2, __result.min))
3042 __result.min = std::forward<decltype(__val2)>(__val2);
3043 if (!__comp_proj(__val1, __result.max))
3044 __result.max = std::move(__val1);
3045 }
3046 }
3047 return __result;
3048 }
3049
3050 template<copyable _Tp, typename _Proj = identity,
3051 indirect_strict_weak_order<projected<const _Tp*, _Proj>>
3052 _Comp = ranges::less>
3053 constexpr minmax_result<_Tp>
3054 operator()(initializer_list<_Tp> __r,
3055 _Comp __comp = {}, _Proj __proj = {}) const
3056 {
3057 return (*this)(ranges::subrange(__r),
3058 std::move(__comp), std::move(__proj));
3059 }
3060 };
3061
3062 inline constexpr __minmax_fn minmax{};
3063
3064 struct __min_element_fn
3065 {
3066 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
3067 typename _Proj = identity,
3068 indirect_strict_weak_order<projected<_Iter, _Proj>>
3069 _Comp = ranges::less>
3070 constexpr _Iter
3071 operator()(_Iter __first, _Sent __last,
3072 _Comp __comp = {}, _Proj __proj = {}) const
3073 {
3074 if (__first == __last)
3075 return __first;
3076
3077 auto __i = __first;
3078 while (++__i != __last)
3079 {
3080 if (std::__invoke(__comp,
3081 std::__invoke(__proj, *__i),
3082 std::__invoke(__proj, *__first)))
3083 __first = __i;
3084 }
3085 return __first;
3086 }
3087
3088 template<forward_range _Range, typename _Proj = identity,
3089 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
3090 _Comp = ranges::less>
3091 constexpr borrowed_iterator_t<_Range>
3092 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
3093 {
3094 return (*this)(ranges::begin(__r), ranges::end(__r),
3095 std::move(__comp), std::move(__proj));
3096 }
3097 };
3098
3099 inline constexpr __min_element_fn min_element{};
3100
3101 struct __max_element_fn
3102 {
3103 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
3104 typename _Proj = identity,
3105 indirect_strict_weak_order<projected<_Iter, _Proj>>
3106 _Comp = ranges::less>
3107 constexpr _Iter
3108 operator()(_Iter __first, _Sent __last,
3109 _Comp __comp = {}, _Proj __proj = {}) const
3110 {
3111 if (__first == __last)
3112 return __first;
3113
3114 auto __i = __first;
3115 while (++__i != __last)
3116 {
3117 if (std::__invoke(__comp,
3118 std::__invoke(__proj, *__first),
3119 std::__invoke(__proj, *__i)))
3120 __first = __i;
3121 }
3122 return __first;
3123 }
3124
3125 template<forward_range _Range, typename _Proj = identity,
3126 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
3127 _Comp = ranges::less>
3128 constexpr borrowed_iterator_t<_Range>
3129 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
3130 {
3131 return (*this)(ranges::begin(__r), ranges::end(__r),
3132 std::move(__comp), std::move(__proj));
3133 }
3134 };
3135
3136 inline constexpr __max_element_fn max_element{};
3137
3138 template<typename _Iter>
3139 using minmax_element_result = min_max_result<_Iter>;
3140
3141 struct __minmax_element_fn
3142 {
3143 template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
3144 typename _Proj = identity,
3145 indirect_strict_weak_order<projected<_Iter, _Proj>>
3146 _Comp = ranges::less>
3147 constexpr minmax_element_result<_Iter>
3148 operator()(_Iter __first, _Sent __last,
3149 _Comp __comp = {}, _Proj __proj = {}) const
3150 {
3151 auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
3152 minmax_element_result<_Iter> __result = {__first, __first};
3153 if (__first == __last || ++__first == __last)
3154 return __result;
3155 else
3156 {
3157 // At this point __result.min == __result.max, so a single
3158 // comparison with the next element suffices.
3159 if (__comp_proj(*__first, *__result.min))
3160 __result.min = __first;
3161 else
3162 __result.max = __first;
3163 }
3164 while (++__first != __last)
3165 {
3166 // Now process two elements at a time so that we perform at most
3167 // 1 + 3*(N-2)/2 comparisons in total (each of the (N-2)/2
3168 // iterations of this loop performs three comparisons).
3169 auto __prev = __first;
3170 if (++__first == __last)
3171 {
3172 // N is odd; in this final iteration, we perform at most two
3173 // comparisons, for a total of 1 + 3*(N-3)/2 + 2 comparisons,
3174 // which is not more than 3*N/2, as required.
3175 if (__comp_proj(*__prev, *__result.min))
3176 __result.min = __prev;
3177 else if (!__comp_proj(*__prev, *__result.max))
3178 __result.max = __prev;
3179 break;
3180 }
3181 if (!__comp_proj(*__first, *__prev))
3182 {
3183 if (__comp_proj(*__prev, *__result.min))
3184 __result.min = __prev;
3185 if (!__comp_proj(*__first, *__result.max))
3186 __result.max = __first;
3187 }
3188 else
3189 {
3190 if (__comp_proj(*__first, *__result.min))
3191 __result.min = __first;
3192 if (!__comp_proj(*__prev, *__result.max))
3193 __result.max = __prev;
3194 }
3195 }
3196 return __result;
3197 }
3198
3199 template<forward_range _Range, typename _Proj = identity,
3200 indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
3201 _Comp = ranges::less>
3202 constexpr minmax_element_result<borrowed_iterator_t<_Range>>
3203 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
3204 {
3205 return (*this)(ranges::begin(__r), ranges::end(__r),
3206 std::move(__comp), std::move(__proj));
3207 }
3208 };
3209
3210 inline constexpr __minmax_element_fn minmax_element{};
3211
3212 struct __lexicographical_compare_fn
3213 {
3214 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
3215 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
3216 typename _Proj1 = identity, typename _Proj2 = identity,
3217 indirect_strict_weak_order<projected<_Iter1, _Proj1>,
3218 projected<_Iter2, _Proj2>>
3219 _Comp = ranges::less>
3220 constexpr bool
3221 operator()(_Iter1 __first1, _Sent1 __last1,
3222 _Iter2 __first2, _Sent2 __last2,
3223 _Comp __comp = {},
3224 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
3225 {
3226 if constexpr (__detail::__is_normal_iterator<_Iter1>
3227 && same_as<_Iter1, _Sent1>)
3228 return (*this)(__first1.base(), __last1.base(),
3229 std::move(__first2), std::move(__last2),
3230 std::move(__comp),
3231 std::move(__proj1), std::move(__proj2));
3232 else if constexpr (__detail::__is_normal_iterator<_Iter2>
3233 && same_as<_Iter2, _Sent2>)
3234 return (*this)(std::move(__first1), std::move(__last1),
3235 __first2.base(), __last2.base(),
3236 std::move(__comp),
3237 std::move(__proj1), std::move(__proj2));
3238 else
3239 {
3240 constexpr bool __sized_iters
3241 = (sized_sentinel_for<_Sent1, _Iter1>
3242 && sized_sentinel_for<_Sent2, _Iter2>);
3243 if constexpr (__sized_iters)
3244 {
3245 using _ValueType1 = iter_value_t<_Iter1>;
3246 using _ValueType2 = iter_value_t<_Iter2>;
3247 // This condition is consistent with the one in
3248 // __lexicographical_compare_aux in <bits/stl_algobase.h>.
3249 constexpr bool __use_memcmp
3250 = (__is_memcmp_ordered_with<_ValueType1, _ValueType2>::__value
3251 && __ptr_to_nonvolatile<_Iter1>
3252 && __ptr_to_nonvolatile<_Iter2>
3253 && (is_same_v<_Comp, ranges::less>
3254 || is_same_v<_Comp, ranges::greater>)
3255 && is_same_v<_Proj1, identity>
3256 && is_same_v<_Proj2, identity>);
3257 if constexpr (__use_memcmp)
3258 {
3259 const auto __d1 = __last1 - __first1;
3260 const auto __d2 = __last2 - __first2;
3261
3262 if (const auto __len = std::min(__d1, __d2))
3263 {
3264 const auto __c
3265 = std::__memcmp(__first1, __first2, __len);
3266 if constexpr (is_same_v<_Comp, ranges::less>)
3267 {
3268 if (__c < 0)
3269 return true;
3270 if (__c > 0)
3271 return false;
3272 }
3273 else if constexpr (is_same_v<_Comp, ranges::greater>)
3274 {
3275 if (__c > 0)
3276 return true;
3277 if (__c < 0)
3278 return false;
3279 }
3280 }
3281 return __d1 < __d2;
3282 }
3283 }
3284
3285 for (; __first1 != __last1 && __first2 != __last2;
3286 ++__first1, (void) ++__first2)
3287 {
3288 if (std::__invoke(__comp,
3289 std::__invoke(__proj1, *__first1),
3290 std::__invoke(__proj2, *__first2)))
3291 return true;
3292 if (std::__invoke(__comp,
3293 std::__invoke(__proj2, *__first2),
3294 std::__invoke(__proj1, *__first1)))
3295 return false;
3296 }
3297 return __first1 == __last1 && __first2 != __last2;
3298 }
3299 }
3300
3301 template<input_range _Range1, input_range _Range2,
3302 typename _Proj1 = identity, typename _Proj2 = identity,
3303 indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
3304 projected<iterator_t<_Range2>, _Proj2>>
3305 _Comp = ranges::less>
3306 constexpr bool
3307 operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {},
3308 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
3309 {
3310 return (*this)(ranges::begin(__r1), ranges::end(__r1),
3311 ranges::begin(__r2), ranges::end(__r2),
3312 std::move(__comp),
3313 std::move(__proj1), std::move(__proj2));
3314 }
3315
3316 private:
3317 template<typename _Iter, typename _Ref = iter_reference_t<_Iter>>
3318 static constexpr bool __ptr_to_nonvolatile
3319 = is_pointer_v<_Iter> && !is_volatile_v<remove_reference_t<_Ref>>;
3320 };
3321
3322 inline constexpr __lexicographical_compare_fn lexicographical_compare;
3323
3324 template<typename _Iter>
3325 struct in_found_result
3326 {
3327 [[no_unique_address]] _Iter in;
3328 bool found;
3329
3330 template<typename _Iter2>
3331 requires convertible_to<const _Iter&, _Iter2>
3332 constexpr
3333 operator in_found_result<_Iter2>() const &
3334 { return {in, found}; }
3335
3336 template<typename _Iter2>
3337 requires convertible_to<_Iter, _Iter2>
3338 constexpr
3339 operator in_found_result<_Iter2>() &&
3340 { return {std::move(in), found}; }
3341 };
3342
3343 template<typename _Iter>
3344 using next_permutation_result = in_found_result<_Iter>;
3345
3346 struct __next_permutation_fn
3347 {
3348 template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
3349 typename _Comp = ranges::less, typename _Proj = identity>
3350 requires sortable<_Iter, _Comp, _Proj>
3351 constexpr next_permutation_result<_Iter>
3352 operator()(_Iter __first, _Sent __last,
3353 _Comp __comp = {}, _Proj __proj = {}) const
3354 {
3355 if (__first == __last)
3356 return {std::move(__first), false};
3357
3358 auto __i = __first;
3359 ++__i;
3360 if (__i == __last)
3361 return {std::move(__i), false};
3362
3363 auto __lasti = ranges::next(__first, __last);
3364 __i = __lasti;
3365 --__i;
3366
3367 for (;;)
3368 {
3369 auto __ii = __i;
3370 --__i;
3371 if (std::__invoke(__comp,
3372 std::__invoke(__proj, *__i),
3373 std::__invoke(__proj, *__ii)))
3374 {
3375 auto __j = __lasti;
3376 while (!(bool)std::__invoke(__comp,
3377 std::__invoke(__proj, *__i),
3378 std::__invoke(__proj, *--__j)))
3379 ;
3380 ranges::iter_swap(__i, __j);
3381 ranges::reverse(__ii, __last);
3382 return {std::move(__lasti), true};
3383 }
3384 if (__i == __first)
3385 {
3386 ranges::reverse(__first, __last);
3387 return {std::move(__lasti), false};
3388 }
3389 }
3390 }
3391
3392 template<bidirectional_range _Range, typename _Comp = ranges::less,
3393 typename _Proj = identity>
3394 requires sortable<iterator_t<_Range>, _Comp, _Proj>
3395 constexpr next_permutation_result<borrowed_iterator_t<_Range>>
3396 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
3397 {
3398 return (*this)(ranges::begin(__r), ranges::end(__r),
3399 std::move(__comp), std::move(__proj));
3400 }
3401 };
3402
3403 inline constexpr __next_permutation_fn next_permutation{};
3404
3405 template<typename _Iter>
3406 using prev_permutation_result = in_found_result<_Iter>;
3407
3408 struct __prev_permutation_fn
3409 {
3410 template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
3411 typename _Comp = ranges::less, typename _Proj = identity>
3412 requires sortable<_Iter, _Comp, _Proj>
3413 constexpr prev_permutation_result<_Iter>
3414 operator()(_Iter __first, _Sent __last,
3415 _Comp __comp = {}, _Proj __proj = {}) const
3416 {
3417 if (__first == __last)
3418 return {std::move(__first), false};
3419
3420 auto __i = __first;
3421 ++__i;
3422 if (__i == __last)
3423 return {std::move(__i), false};
3424
3425 auto __lasti = ranges::next(__first, __last);
3426 __i = __lasti;
3427 --__i;
3428
3429 for (;;)
3430 {
3431 auto __ii = __i;
3432 --__i;
3433 if (std::__invoke(__comp,
3434 std::__invoke(__proj, *__ii),
3435 std::__invoke(__proj, *__i)))
3436 {
3437 auto __j = __lasti;
3438 while (!(bool)std::__invoke(__comp,
3439 std::__invoke(__proj, *--__j),
3440 std::__invoke(__proj, *__i)))
3441 ;
3442 ranges::iter_swap(__i, __j);
3443 ranges::reverse(__ii, __last);
3444 return {std::move(__lasti), true};
3445 }
3446 if (__i == __first)
3447 {
3448 ranges::reverse(__first, __last);
3449 return {std::move(__lasti), false};
3450 }
3451 }
3452 }
3453
3454 template<bidirectional_range _Range, typename _Comp = ranges::less,
3455 typename _Proj = identity>
3456 requires sortable<iterator_t<_Range>, _Comp, _Proj>
3457 constexpr prev_permutation_result<borrowed_iterator_t<_Range>>
3458 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
3459 {
3460 return (*this)(ranges::begin(__r), ranges::end(__r),
3461 std::move(__comp), std::move(__proj));
3462 }
3463 };
3464
3465 inline constexpr __prev_permutation_fn prev_permutation{};
3466
3467} // namespace ranges
3468
3469#define __cpp_lib_shift 201806L
3470 template<typename _ForwardIterator>
3471 constexpr _ForwardIterator
3472 shift_left(_ForwardIterator __first, _ForwardIterator __last,
3473 typename iterator_traits<_ForwardIterator>::difference_type __n)
3474 {
3475 __glibcxx_assert(__n >= 0);
3476 if (__n == 0)
3477 return __last;
3478
3479 auto __mid = ranges::next(__first, __n, __last);
3480 if (__mid == __last)
3481 return __first;
3482 return std::move(std::move(__mid), std::move(__last), std::move(__first));
3483 }
3484
3485 template<typename _ForwardIterator>
3486 constexpr _ForwardIterator
3487 shift_right(_ForwardIterator __first, _ForwardIterator __last,
3488 typename iterator_traits<_ForwardIterator>::difference_type __n)
3489 {
3490 __glibcxx_assert(__n >= 0);
3491 if (__n == 0)
3492 return __first;
3493
3494 using _Cat
3495 = typename iterator_traits<_ForwardIterator>::iterator_category;
3496 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
3497 {
3498 auto __mid = ranges::next(__last, -__n, __first);
3499 if (__mid == __first)
3500 return __last;
3501
3502 return std::move_backward(std::move(__first), std::move(__mid),
3503 std::move(__last));
3504 }
3505 else
3506 {
3507 auto __result = ranges::next(__first, __n, __last);
3508 if (__result == __last)
3509 return __last;
3510
3511 auto __dest_head = __first, __dest_tail = __result;
3512 while (__dest_head != __result)
3513 {
3514 if (__dest_tail == __last)
3515 {
3516 // If we get here, then we must have
3517 // 2*n >= distance(__first, __last)
3518 // i.e. we are shifting out at least half of the range. In
3519 // this case we can safely perform the shift with a single
3520 // move.
3521 std::move(std::move(__first), std::move(__dest_head), __result);
3522 return __result;
3523 }
3524 ++__dest_head;
3525 ++__dest_tail;
3526 }
3527
3528 for (;;)
3529 {
3530 // At the start of each iteration of this outer loop, the range
3531 // [__first, __result) contains those elements that after shifting
3532 // the whole range right by __n, should end up in
3533 // [__dest_head, __dest_tail) in order.
3534
3535 // The below inner loop swaps the elements of [__first, __result)
3536 // and [__dest_head, __dest_tail), while simultaneously shifting
3537 // the latter range by __n.
3538 auto __cursor = __first;
3539 while (__cursor != __result)
3540 {
3541 if (__dest_tail == __last)
3542 {
3543 // At this point the ranges [__first, result) and
3544 // [__dest_head, dest_tail) are disjoint, so we can safely
3545 // move the remaining elements.
3546 __dest_head = std::move(__cursor, __result,
3547 std::move(__dest_head));
3548 std::move(std::move(__first), std::move(__cursor),
3549 std::move(__dest_head));
3550 return __result;
3551 }
3552 std::iter_swap(__cursor, __dest_head);
3553 ++__dest_head;
3554 ++__dest_tail;
3555 ++__cursor;
3556 }
3557 }
3558 }
3559 }
3560
3561_GLIBCXX_END_NAMESPACE_VERSION
3562} // namespace std
3563#endif // concepts
3564#endif // C++20
3565#endif // _RANGES_ALGO_H
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:104
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
Definition: invoke.h:90
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
Definition: any:429
constexpr _BI2 move_backward(_BI1 __first, _BI1 __last, _BI2 __result)
Moves the range [first,last) into result.
Definition: stl_algobase.h:887
constexpr _InputIterator for_each_n(_InputIterator __first, _Size __n, _Function __f)
Apply a function to every element of a sequence.
Definition: stl_algo.h:3852
constexpr const _Tp & clamp(const _Tp &, const _Tp &, const _Tp &)
Returns the value clamped between lo and hi.
Definition: stl_algo.h:3666
constexpr const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
Definition: stl_algobase.h:254
constexpr pair< const _Tp &, const _Tp & > minmax(const _Tp &, const _Tp &)
Determines min and max at once as an ordered pair.
Definition: stl_algo.h:3329
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
Definition: stl_algobase.h:230
ISO C++ entities toplevel namespace is std.
_SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last, _SampleIterator __out, _Distance __n, _UniformRandomBitGenerator &&__g)
Take a random sample from a population.
Definition: stl_algo.h:5914