1 // Core algorithmic facilities -*- C++ -*-
2 
3 // Copyright (C) 2020-2022 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file bits/ranges_algo.h
26  *  This is an internal header file, included by other library headers.
27  *  Do not attempt to use it directly. @headername{algorithm}
28  */
29 
30 #ifndef _RANGES_ALGO_H
31 #define _RANGES_ALGO_H 1
32 
33 #if __cplusplus > 201703L
34 
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
_GLIBCXX_VISIBILITY(default)40 namespace std _GLIBCXX_VISIBILITY(default)
41 {
42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43 namespace 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, __result.min};
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