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