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