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

source code of include/c++/11/bits/ranges_algo.h