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