libstdc++
ranges_algo.h
Go to the documentation of this file.
1 // Core algorithmic facilities -*- C++ -*-
2 
3 // Copyright (C) 2020-2026 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file bits/ranges_algo.h
26  * This is an internal header file, included by other library headers.
27  * Do not attempt to use it directly. @headername{algorithm}
28  */
29 
30 #ifndef _RANGES_ALGO_H
31 #define _RANGES_ALGO_H 1
32 
33 #if __cplusplus > 201703L
34 
35 #include <bit> // __bit_width
36 #if __cplusplus > 202002L
37 #include <optional>
38 #endif
39 #include <bits/ranges_algobase.h>
40 #include <bits/ranges_util.h>
41 #include <bits/uniform_int_dist.h> // concept uniform_random_bit_generator
42 
43 #if __glibcxx_concepts
44 namespace std _GLIBCXX_VISIBILITY(default)
45 {
46 _GLIBCXX_BEGIN_NAMESPACE_VERSION
47 namespace ranges
48 {
49  namespace __detail
50  {
51  template<typename _Fp>
52  using __by_ref_or_value_fn
53  = __conditional_t<is_scalar_v<_Fp> || is_empty_v<_Fp>, _Fp, _Fp&>;
54 
55  template<typename _Comp, typename _Proj>
56  struct _Comp_proj
57  {
58  [[no_unique_address]] __by_ref_or_value_fn<_Comp> _M_comp;
59  [[no_unique_address]] __by_ref_or_value_fn<_Proj> _M_proj;
60 
61  constexpr
62  _Comp_proj(_Comp& __comp, _Proj& __proj)
63  : _M_comp(__comp), _M_proj(__proj)
64  { }
65 
66  template<typename _Tp, typename _Up>
67  constexpr bool
68  operator()(_Tp&& __x, _Up&& __y)
69  {
70  return std::__invoke(_M_comp,
71  std::__invoke(_M_proj, std::forward<_Tp>(__x)),
72  std::__invoke(_M_proj, std::forward<_Up>(__y)));
73  }
74  };
75 
76  template<typename _Comp, typename _Proj>
77  constexpr _Comp_proj<_Comp, _Proj>
78  __make_comp_proj(_Comp& __comp, _Proj& __proj)
79  { return {__comp, __proj}; }
80 
81  template<typename _Pred, typename _Proj>
82  struct _Pred_proj
83  {
84  [[no_unique_address]] __by_ref_or_value_fn<_Pred> _M_pred;
85  [[no_unique_address]] __by_ref_or_value_fn<_Proj> _M_proj;
86 
87  constexpr
88  _Pred_proj(_Pred& __pred, _Proj& __proj)
89  : _M_pred(__pred), _M_proj(__proj)
90  { }
91 
92  template<typename _Tp>
93  constexpr bool
94  operator()(_Tp&& __x)
95  {
96  return std::__invoke(_M_pred,
97  std::__invoke(_M_proj, std::forward<_Tp>(__x)));
98  }
99  };
100 
101  template<typename _Pred, typename _Proj>
102  constexpr _Pred_proj<_Pred, _Proj>
103  __make_pred_proj(_Pred& __pred, _Proj& __proj)
104  { return {__pred, __proj}; }
105  } // namespace __detail
106 
107  struct __all_of_fn
108  {
109  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
110  typename _Proj = identity,
111  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
112  [[nodiscard]] constexpr bool
113  operator()(_Iter __first, _Sent __last,
114  _Pred __pred, _Proj __proj = {}) const
115  {
116  for (; __first != __last; ++__first)
117  if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
118  return false;
119  return true;
120  }
121 
122  template<input_range _Range, typename _Proj = identity,
123  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
124  _Pred>
125  [[nodiscard]] constexpr bool
126  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
127  {
128  return (*this)(ranges::begin(__r), ranges::end(__r),
129  std::move(__pred), std::move(__proj));
130  }
131  };
132 
133  inline constexpr __all_of_fn all_of{};
134 
135  struct __any_of_fn
136  {
137  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
138  typename _Proj = identity,
139  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
140  [[nodiscard]] constexpr bool
141  operator()(_Iter __first, _Sent __last,
142  _Pred __pred, _Proj __proj = {}) const
143  {
144  for (; __first != __last; ++__first)
145  if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
146  return true;
147  return false;
148  }
149 
150  template<input_range _Range, typename _Proj = identity,
151  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
152  _Pred>
153  [[nodiscard]] constexpr bool
154  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
155  {
156  return (*this)(ranges::begin(__r), ranges::end(__r),
157  std::move(__pred), std::move(__proj));
158  }
159  };
160 
161  inline constexpr __any_of_fn any_of{};
162 
163  struct __none_of_fn
164  {
165  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
166  typename _Proj = identity,
167  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
168  [[nodiscard]] constexpr bool
169  operator()(_Iter __first, _Sent __last,
170  _Pred __pred, _Proj __proj = {}) const
171  {
172  for (; __first != __last; ++__first)
173  if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
174  return false;
175  return true;
176  }
177 
178  template<input_range _Range, typename _Proj = identity,
179  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
180  _Pred>
181  [[nodiscard]] constexpr bool
182  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
183  {
184  return (*this)(ranges::begin(__r), ranges::end(__r),
185  std::move(__pred), std::move(__proj));
186  }
187  };
188 
189  inline constexpr __none_of_fn none_of{};
190 
191  template<typename _Iter, typename _Fp>
192  struct in_fun_result
193  {
194  [[no_unique_address]] _Iter in;
195  [[no_unique_address]] _Fp fun;
196 
197  template<typename _Iter2, typename _F2p>
198  requires convertible_to<const _Iter&, _Iter2>
199  && convertible_to<const _Fp&, _F2p>
200  constexpr
201  operator in_fun_result<_Iter2, _F2p>() const &
202  { return {in, fun}; }
203 
204  template<typename _Iter2, typename _F2p>
205  requires convertible_to<_Iter, _Iter2> && convertible_to<_Fp, _F2p>
206  constexpr
207  operator in_fun_result<_Iter2, _F2p>() &&
208  { return {std::move(in), std::move(fun)}; }
209  };
210 
211  template<typename _Iter, typename _Fp>
212  using for_each_result = in_fun_result<_Iter, _Fp>;
213 
214  struct __for_each_fn
215  {
216  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
217  typename _Proj = identity,
218  indirectly_unary_invocable<projected<_Iter, _Proj>> _Fun>
219  constexpr for_each_result<_Iter, _Fun>
220  operator()(_Iter __first, _Sent __last, _Fun __f, _Proj __proj = {}) const
221  {
222  for (; __first != __last; ++__first)
223  std::__invoke(__f, std::__invoke(__proj, *__first));
224  return { std::move(__first), std::move(__f) };
225  }
226 
227  template<input_range _Range, typename _Proj = identity,
228  indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>>
229  _Fun>
230  constexpr for_each_result<borrowed_iterator_t<_Range>, _Fun>
231  operator()(_Range&& __r, _Fun __f, _Proj __proj = {}) const
232  {
233  return (*this)(ranges::begin(__r), ranges::end(__r),
234  std::move(__f), std::move(__proj));
235  }
236  };
237 
238  inline constexpr __for_each_fn for_each{};
239 
240  template<typename _Iter, typename _Fp>
241  using for_each_n_result = in_fun_result<_Iter, _Fp>;
242 
243  struct __for_each_n_fn
244  {
245  template<input_iterator _Iter, typename _Proj = identity,
246  indirectly_unary_invocable<projected<_Iter, _Proj>> _Fun>
247  constexpr for_each_n_result<_Iter, _Fun>
248  operator()(_Iter __first, iter_difference_t<_Iter> __n,
249  _Fun __f, _Proj __proj = {}) const
250  {
251  if constexpr (random_access_iterator<_Iter>)
252  {
253  if (__n <= 0)
254  return {std::move(__first), std::move(__f)};
255  auto __last = __first + __n;
256  return ranges::for_each(std::move(__first), std::move(__last),
257  std::move(__f), std::move(__proj));
258  }
259  else
260  {
261  while (__n-- > 0)
262  {
263  std::__invoke(__f, std::__invoke(__proj, *__first));
264  ++__first;
265  }
266  return {std::move(__first), std::move(__f)};
267  }
268  }
269  };
270 
271  inline constexpr __for_each_n_fn for_each_n{};
272 
273  // find, find_if and find_if_not are defined in <bits/ranges_util.h>.
274 
275  struct __find_first_of_fn
276  {
277  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
278  forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
279  typename _Pred = ranges::equal_to,
280  typename _Proj1 = identity, typename _Proj2 = identity>
281  requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
282  [[nodiscard]] constexpr _Iter1
283  operator()(_Iter1 __first1, _Sent1 __last1,
284  _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
285  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
286  {
287  for (; __first1 != __last1; ++__first1)
288  for (auto __iter = __first2; __iter != __last2; ++__iter)
289  if (std::__invoke(__pred,
290  std::__invoke(__proj1, *__first1),
291  std::__invoke(__proj2, *__iter)))
292  return __first1;
293  return __first1;
294  }
295 
296  template<input_range _Range1, forward_range _Range2,
297  typename _Pred = ranges::equal_to,
298  typename _Proj1 = identity, typename _Proj2 = identity>
299  requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
300  _Pred, _Proj1, _Proj2>
301  [[nodiscard]] constexpr borrowed_iterator_t<_Range1>
302  operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
303  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
304  {
305  return (*this)(ranges::begin(__r1), ranges::end(__r1),
306  ranges::begin(__r2), ranges::end(__r2),
307  std::move(__pred),
308  std::move(__proj1), std::move(__proj2));
309  }
310  };
311 
312  inline constexpr __find_first_of_fn find_first_of{};
313 
314  struct __count_fn
315  {
316  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
317  typename _Proj = identity,
318  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
319  requires indirect_binary_predicate<ranges::equal_to,
320  projected<_Iter, _Proj>,
321  const _Tp*>
322  [[nodiscard]] constexpr iter_difference_t<_Iter>
323  operator()(_Iter __first, _Sent __last,
324  const _Tp& __value, _Proj __proj = {}) const
325  {
326  iter_difference_t<_Iter> __n = 0;
327  for (; __first != __last; ++__first)
328  if (std::__invoke(__proj, *__first) == __value)
329  ++__n;
330  return __n;
331  }
332 
333  template<input_range _Range, typename _Proj = identity,
334  typename _Tp
335  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj)>
336  requires indirect_binary_predicate<ranges::equal_to,
337  projected<iterator_t<_Range>, _Proj>,
338  const _Tp*>
339  [[nodiscard]] constexpr range_difference_t<_Range>
340  operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
341  {
342  return (*this)(ranges::begin(__r), ranges::end(__r),
343  __value, std::move(__proj));
344  }
345  };
346 
347  inline constexpr __count_fn count{};
348 
349  struct __count_if_fn
350  {
351  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
352  typename _Proj = identity,
353  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
354  constexpr iter_difference_t<_Iter>
355  operator()(_Iter __first, _Sent __last,
356  _Pred __pred, _Proj __proj = {}) const
357  {
358  iter_difference_t<_Iter> __n = 0;
359  for (; __first != __last; ++__first)
360  if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
361  ++__n;
362  return __n;
363  }
364 
365  template<input_range _Range,
366  typename _Proj = identity,
367  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
368  _Pred>
369  constexpr range_difference_t<_Range>
370  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
371  {
372  return (*this)(ranges::begin(__r), ranges::end(__r),
373  std::move(__pred), std::move(__proj));
374  }
375  };
376 
377  inline constexpr __count_if_fn count_if{};
378 
379  // in_in_result, mismatch and search are defined in <bits/ranges_util.h>.
380 
381  struct __search_n_fn
382  {
383  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
384  typename _Pred = ranges::equal_to, typename _Proj = identity,
385  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
386  requires indirectly_comparable<_Iter, const _Tp*, _Pred, _Proj>
387  constexpr subrange<_Iter>
388  operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __count,
389  const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const
390  {
391  if (__count <= 0)
392  return {__first, __first};
393 
394  auto __value_comp = [&] <typename _Rp> (_Rp&& __arg) -> bool {
395  return std::__invoke(__pred, std::forward<_Rp>(__arg), __value);
396  };
397  if (__count == 1)
398  {
399  __first = ranges::find_if(std::move(__first), __last,
400  std::move(__value_comp),
401  std::move(__proj));
402  if (__first == __last)
403  return {__first, __first};
404  else
405  {
406  auto __end = __first;
407  return {__first, ++__end};
408  }
409  }
410 
411  if constexpr (sized_sentinel_for<_Sent, _Iter>
412  && random_access_iterator<_Iter>)
413  {
414  auto __tail_size = __last - __first;
415  auto __remainder = __count;
416 
417  while (__remainder <= __tail_size)
418  {
419  __first += __remainder;
420  __tail_size -= __remainder;
421  auto __backtrack = __first;
422  while (__value_comp(std::__invoke(__proj, *--__backtrack)))
423  {
424  if (--__remainder == 0)
425  return {__first - __count, __first};
426  }
427  __remainder = __count + 1 - (__first - __backtrack);
428  }
429  auto __i = __first + __tail_size;
430  return {__i, __i};
431  }
432  else
433  {
434  __first = ranges::find_if(__first, __last, __value_comp, __proj);
435  while (__first != __last)
436  {
437  auto __n = __count;
438  auto __i = __first;
439  ++__i;
440  while (__i != __last && __n != 1
441  && __value_comp(std::__invoke(__proj, *__i)))
442  {
443  ++__i;
444  --__n;
445  }
446  if (__n == 1)
447  return {__first, __i};
448  if (__i == __last)
449  return {__i, __i};
450  __first = ranges::find_if(++__i, __last, __value_comp, __proj);
451  }
452  return {__first, __first};
453  }
454  }
455 
456  template<forward_range _Range,
457  typename _Pred = ranges::equal_to, typename _Proj = identity,
458  typename _Tp
459  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj)>
460  requires indirectly_comparable<iterator_t<_Range>, const _Tp*,
461  _Pred, _Proj>
462  constexpr borrowed_subrange_t<_Range>
463  operator()(_Range&& __r, range_difference_t<_Range> __count,
464  const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const
465  {
466  return (*this)(ranges::begin(__r), ranges::end(__r),
467  std::move(__count), __value,
468  std::move(__pred), std::move(__proj));
469  }
470  };
471 
472  inline constexpr __search_n_fn search_n{};
473 
474 #if __glibcxx_ranges_starts_ends_with // C++ >= 23
475  struct __starts_with_fn
476  {
477  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
478  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
479  typename _Pred = ranges::equal_to,
480  typename _Proj1 = identity, typename _Proj2 = identity>
481  requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
482  constexpr bool
483  operator()(_Iter1 __first1, _Sent1 __last1,
484  _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
485  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
486  {
487  iter_difference_t<_Iter1> __n1 = -1;
488  iter_difference_t<_Iter2> __n2 = -1;
489  if constexpr (sized_sentinel_for<_Sent1, _Iter1>)
490  __n1 = __last1 - __first1;
491  if constexpr (sized_sentinel_for<_Sent2, _Iter2>)
492  __n2 = __last2 - __first2;
493  return _S_impl(std::move(__first1), __last1, __n1,
494  std::move(__first2), __last2, __n2,
495  std::move(__pred),
496  std::move(__proj1), std::move(__proj2));
497  }
498 
499  template<input_range _Range1, input_range _Range2,
500  typename _Pred = ranges::equal_to,
501  typename _Proj1 = identity, typename _Proj2 = identity>
502  requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
503  _Pred, _Proj1, _Proj2>
504  constexpr bool
505  operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
506  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
507  {
508  range_difference_t<_Range1> __n1 = -1;
509  range_difference_t<_Range2> __n2 = -1;
510  if constexpr (sized_range<_Range1>)
511  __n1 = ranges::size(__r1);
512  if constexpr (sized_range<_Range2>)
513  __n2 = ranges::size(__r2);
514  return _S_impl(ranges::begin(__r1), ranges::end(__r1), __n1,
515  ranges::begin(__r2), ranges::end(__r2), __n2,
516  std::move(__pred),
517  std::move(__proj1), std::move(__proj2));
518  }
519 
520  private:
521  template<typename _Iter1, typename _Sent1, typename _Iter2, typename _Sent2,
522  typename _Pred,
523  typename _Proj1, typename _Proj2>
524  static constexpr bool
525  _S_impl(_Iter1 __first1, _Sent1 __last1, iter_difference_t<_Iter1> __n1,
526  _Iter2 __first2, _Sent2 __last2, iter_difference_t<_Iter2> __n2,
527  _Pred __pred, _Proj1 __proj1, _Proj2 __proj2)
528  {
529  if (__first2 == __last2) [[unlikely]]
530  return true;
531  else if (__n1 == -1 || __n2 == -1)
532  return ranges::mismatch(std::move(__first1), __last1,
533  std::move(__first2), __last2,
534  std::move(__pred),
535  std::move(__proj1), std::move(__proj2)).in2 == __last2;
536  else if (__n1 < __n2)
537  return false;
538  else if constexpr (random_access_iterator<_Iter1>)
539  return ranges::equal(__first1, __first1 + iter_difference_t<_Iter1>(__n2),
540  std::move(__first2), __last2,
541  std::move(__pred),
542  std::move(__proj1), std::move(__proj2));
543  else
544  return ranges::equal(counted_iterator(std::move(__first1),
545  iter_difference_t<_Iter1>(__n2)),
547  std::move(__first2), __last2,
548  std::move(__pred),
549  std::move(__proj1), std::move(__proj2));
550  }
551 
552  friend struct __ends_with_fn;
553  };
554 
555  inline constexpr __starts_with_fn starts_with{};
556 
557  struct __ends_with_fn
558  {
559  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
560  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
561  typename _Pred = ranges::equal_to,
562  typename _Proj1 = identity, typename _Proj2 = identity>
563  requires (forward_iterator<_Iter1> || sized_sentinel_for<_Sent1, _Iter1>)
564  && (forward_iterator<_Iter2> || sized_sentinel_for<_Sent2, _Iter2>)
565  && indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
566  constexpr bool
567  operator()(_Iter1 __first1, _Sent1 __last1,
568  _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
569  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
570  {
571  iter_difference_t<_Iter1> __n1 = -1;
572  iter_difference_t<_Iter2> __n2 = -1;
573  if constexpr (sized_sentinel_for<_Sent1, _Iter1>)
574  __n1 = __last1 - __first1;
575  if constexpr (sized_sentinel_for<_Sent2, _Iter2>)
576  __n2 = __last2 - __first2;
577  return _S_impl(std::move(__first1), __last1, __n1,
578  std::move(__first2), __last2, __n2,
579  std::move(__pred),
580  std::move(__proj1), std::move(__proj2));
581  }
582 
583  template<input_range _Range1, input_range _Range2,
584  typename _Pred = ranges::equal_to,
585  typename _Proj1 = identity, typename _Proj2 = identity>
586  requires (forward_range<_Range1> || sized_range<_Range1>)
587  && (forward_range<_Range2> || sized_range<_Range2>)
588  && indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
589  _Pred, _Proj1, _Proj2>
590  constexpr bool
591  operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
592  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
593  {
594  range_difference_t<_Range1> __n1 = -1;
595  range_difference_t<_Range2> __n2 = -1;
596  if constexpr (sized_range<_Range1>)
597  __n1 = ranges::size(__r1);
598  if constexpr (sized_range<_Range2>)
599  __n2 = ranges::size(__r2);
600  return _S_impl(ranges::begin(__r1), ranges::end(__r1), __n1,
601  ranges::begin(__r2), ranges::end(__r2), __n2,
602  std::move(__pred),
603  std::move(__proj1), std::move(__proj2));
604  }
605 
606  private:
607  template<typename _Iter1, typename _Sent1,
608  typename _Iter2, typename _Sent2,
609  typename _Pred,
610  typename _Proj1, typename _Proj2>
611  static constexpr bool
612  _S_impl(_Iter1 __first1, _Sent1 __last1, iter_difference_t<_Iter1> __n1,
613  _Iter2 __first2, _Sent2 __last2, iter_difference_t<_Iter2> __n2,
614  _Pred __pred, _Proj1 __proj1, _Proj2 __proj2)
615  {
616  if constexpr (!random_access_iterator<_Iter1>
617  && bidirectional_iterator<_Iter1> && same_as<_Iter1, _Sent1>
618  && bidirectional_iterator<_Iter2> && same_as<_Iter2, _Sent2>)
619  return starts_with._S_impl(std::make_reverse_iterator(__last1),
620  std::make_reverse_iterator(__first1),
621  __n1,
623  std::make_reverse_iterator(__first2),
624  __n2,
625  std::move(__pred),
626  std::move(__proj1), std::move(__proj2));
627 
628  if (__first2 == __last2) [[unlikely]]
629  return true;
630 
631  if constexpr (forward_iterator<_Iter2>)
632  if (__n2 == -1)
633  __n2 = ranges::distance(__first2, __last2);
634 
635  // __glibcxx_assert(__n2 != -1);
636 
637  if (__n1 != -1)
638  {
639  if (__n1 < __n2)
640  return false;
641  auto __shift = __n1 - iter_difference_t<_Iter1>(__n2);
642  if (random_access_iterator<_Iter1>
643  || !bidirectional_iterator<_Iter1>
644  || !same_as<_Iter1, _Sent1>
645  || __shift < __n2)
646  {
647  ranges::advance(__first1, __shift);
648  return ranges::equal(std::move(__first1), __last1,
649  std::move(__first2), __last2,
650  std::move(__pred),
651  std::move(__proj1), std::move(__proj2));
652  }
653  }
654 
655  if constexpr (bidirectional_iterator<_Iter1> && same_as<_Iter1, _Sent1>)
656  {
657  _Iter1 __it1 = __last1;
658  if (__n1 != -1)
659  ranges::advance(__it1, -iter_difference_t<_Iter1>(__n2));
660  else
661  {
662  // We can't use ranges::advance if the haystack size is
663  // unknown, since we need to detect and return false if
664  // it's smaller than the needle.
665  iter_difference_t<_Iter2> __m = __n2;
666  while (__m != 0 && __it1 != __first1)
667  {
668  --__m;
669  --__it1;
670  }
671  if (__m != 0)
672  return false;
673  }
674  return ranges::equal(__it1, __last1,
675  std::move(__first2), __last2,
676  std::move(__pred),
677  std::move(__proj1), std::move(__proj2));
678  }
679  else if constexpr (forward_iterator<_Iter1>)
680  {
681  // __glibcxx_assert(__n1 == -1);
682  _Iter1 __prev_first1;
683  __n1 = 0;
684  while (true)
685  {
686  iter_difference_t<_Iter2> __m = __n2;
687  _Iter1 __it1 = __first1;
688  while (__m != 0 && __it1 != __last1)
689  {
690  ++__n1;
691  --__m;
692  ++__it1;
693  }
694  if (__m != 0)
695  {
696  // __glibcxx_assert(__it1 == __last1);
697  if (__n1 < __n2)
698  return false;
699  __first1 = ranges::next(__prev_first1,
700  iter_difference_t<_Iter1>(__n2 - __m));
701  break;
702  }
703  __prev_first1 = __first1;
704  __first1 = __it1;
705  }
706  return ranges::equal(__first1, __last1,
707  std::move(__first2), __last2,
708  std::move(__pred),
709  std::move(__proj1), std::move(__proj2));
710  }
711  else
712  // If the haystack is non-forward then it must be sized, in which case
713  // we already returned via the __n1 != 1 case.
714  __builtin_unreachable();
715  }
716 
717  };
718 
719  inline constexpr __ends_with_fn ends_with{};
720 #endif // __glibcxx_ranges_starts_ends_with
721 
722  struct __find_end_fn
723  {
724  template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
725  forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
726  typename _Pred = ranges::equal_to,
727  typename _Proj1 = identity, typename _Proj2 = identity>
728  requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
729  [[nodiscard]] constexpr subrange<_Iter1>
730  operator()(_Iter1 __first1, _Sent1 __last1,
731  _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
732  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
733  {
734  if constexpr (bidirectional_iterator<_Iter1>
735  && bidirectional_iterator<_Iter2>)
736  {
737  auto __i1 = ranges::next(__first1, __last1);
738  auto __i2 = ranges::next(__first2, __last2);
739  auto __rresult
740  = ranges::search(reverse_iterator<_Iter1>{__i1},
741  reverse_iterator<_Iter1>{__first1},
742  reverse_iterator<_Iter2>{__i2},
743  reverse_iterator<_Iter2>{__first2},
744  std::move(__pred),
745  std::move(__proj1), std::move(__proj2));
746  auto __result_first = ranges::end(__rresult).base();
747  auto __result_last = ranges::begin(__rresult).base();
748  if (__result_last == __first1)
749  return {__i1, __i1};
750  else
751  return {__result_first, __result_last};
752  }
753  else
754  {
755  auto __i = ranges::next(__first1, __last1);
756  if (__first2 == __last2)
757  return {__i, __i};
758 
759  auto __result_begin = __i;
760  auto __result_end = __i;
761  for (;;)
762  {
763  auto __new_range = ranges::search(__first1, __last1,
764  __first2, __last2,
765  __pred, __proj1, __proj2);
766  auto __new_result_begin = ranges::begin(__new_range);
767  auto __new_result_end = ranges::end(__new_range);
768  if (__new_result_begin == __last1)
769  return {__result_begin, __result_end};
770  else
771  {
772  __result_begin = __new_result_begin;
773  __result_end = __new_result_end;
774  __first1 = __result_begin;
775  ++__first1;
776  }
777  }
778  }
779  }
780 
781  template<forward_range _Range1, forward_range _Range2,
782  typename _Pred = ranges::equal_to,
783  typename _Proj1 = identity, typename _Proj2 = identity>
784  requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
785  _Pred, _Proj1, _Proj2>
786  [[nodiscard]] constexpr borrowed_subrange_t<_Range1>
787  operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
788  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
789  {
790  return (*this)(ranges::begin(__r1), ranges::end(__r1),
791  ranges::begin(__r2), ranges::end(__r2),
792  std::move(__pred),
793  std::move(__proj1), std::move(__proj2));
794  }
795  };
796 
797  inline constexpr __find_end_fn find_end{};
798 
799  // adjacent_find is defined in <bits/ranges_util.h>.
800 
801  struct __is_permutation_fn
802  {
803  template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
804  forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
805  typename _Proj1 = identity, typename _Proj2 = identity,
806  indirect_equivalence_relation<projected<_Iter1, _Proj1>,
807  projected<_Iter2, _Proj2>> _Pred
808  = ranges::equal_to>
809  [[nodiscard]] constexpr bool
810  operator()(_Iter1 __first1, _Sent1 __last1,
811  _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
812  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
813  {
814  constexpr bool __sized_iters
815  = (sized_sentinel_for<_Sent1, _Iter1>
816  && sized_sentinel_for<_Sent2, _Iter2>);
817  if constexpr (__sized_iters)
818  {
819  auto __d1 = ranges::distance(__first1, __last1);
820  auto __d2 = ranges::distance(__first2, __last2);
821  if (__d1 != __d2)
822  return false;
823  }
824 
825  // Efficiently compare identical prefixes: O(N) if sequences
826  // have the same elements in the same order.
827  for (; __first1 != __last1 && __first2 != __last2;
828  ++__first1, (void)++__first2)
829  if (!(bool)std::__invoke(__pred,
830  std::__invoke(__proj1, *__first1),
831  std::__invoke(__proj2, *__first2)))
832  break;
833 
834  if constexpr (__sized_iters)
835  {
836  if (__first1 == __last1)
837  return true;
838  }
839  else
840  {
841  auto __d1 = ranges::distance(__first1, __last1);
842  auto __d2 = ranges::distance(__first2, __last2);
843  if (__d1 == 0 && __d2 == 0)
844  return true;
845  if (__d1 != __d2)
846  return false;
847  }
848 
849  for (auto __scan = __first1; __scan != __last1; ++__scan)
850  {
851  auto&& __scan_deref = *__scan;
852  auto&& __proj_scan =
853  std::__invoke(__proj1, std::forward<decltype(__scan_deref)>(__scan_deref));
854  auto __comp_scan = [&] <typename _Tp> (_Tp&& __arg) -> bool {
855  return std::__invoke(__pred,
856  std::forward<decltype(__proj_scan)>(__proj_scan),
857  std::forward<_Tp>(__arg));
858  };
859  if (__scan != ranges::find_if(__first1, __scan,
860  __comp_scan, __proj1))
861  continue; // We've seen this one before.
862 
863  auto __matches = ranges::count_if(__first2, __last2,
864  __comp_scan, __proj2);
865  if (__matches == 0
866  || ranges::count_if(__scan, __last1,
867  __comp_scan, __proj1) != __matches)
868  return false;
869  }
870  return true;
871  }
872 
873  template<forward_range _Range1, forward_range _Range2,
874  typename _Proj1 = identity, typename _Proj2 = identity,
875  indirect_equivalence_relation<
876  projected<iterator_t<_Range1>, _Proj1>,
877  projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to>
878  [[nodiscard]] constexpr bool
879  operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
880  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
881  {
882  // _GLIBCXX_RESOLVE_LIB_DEFECTS
883  // 3560. ranges::is_permutation should short-circuit for sized_ranges
884  if constexpr (sized_range<_Range1>)
885  if constexpr (sized_range<_Range2>)
886  if (ranges::distance(__r1) != ranges::distance(__r2))
887  return false;
888 
889  return (*this)(ranges::begin(__r1), ranges::end(__r1),
890  ranges::begin(__r2), ranges::end(__r2),
891  std::move(__pred),
892  std::move(__proj1), std::move(__proj2));
893  }
894  };
895 
896  inline constexpr __is_permutation_fn is_permutation{};
897 
898  template<typename _Iter, typename _Out>
899  using copy_if_result = in_out_result<_Iter, _Out>;
900 
901  struct __copy_if_fn
902  {
903  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
904  weakly_incrementable _Out, typename _Proj = identity,
905  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
906  requires indirectly_copyable<_Iter, _Out>
907  constexpr copy_if_result<_Iter, _Out>
908  operator()(_Iter __first, _Sent __last, _Out __result,
909  _Pred __pred, _Proj __proj = {}) const
910  {
911  for (; __first != __last; ++__first)
912  if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
913  {
914  *__result = *__first;
915  ++__result;
916  }
917  return {std::move(__first), std::move(__result)};
918  }
919 
920  template<input_range _Range, weakly_incrementable _Out,
921  typename _Proj = identity,
922  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
923  _Pred>
924  requires indirectly_copyable<iterator_t<_Range>, _Out>
925  constexpr copy_if_result<borrowed_iterator_t<_Range>, _Out>
926  operator()(_Range&& __r, _Out __result,
927  _Pred __pred, _Proj __proj = {}) const
928  {
929  return (*this)(ranges::begin(__r), ranges::end(__r),
930  std::move(__result),
931  std::move(__pred), std::move(__proj));
932  }
933  };
934 
935  inline constexpr __copy_if_fn copy_if{};
936 
937  template<typename _Iter1, typename _Iter2>
938  using swap_ranges_result = in_in_result<_Iter1, _Iter2>;
939 
940  struct __swap_ranges_fn
941  {
942  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
943  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2>
944  requires indirectly_swappable<_Iter1, _Iter2>
945  constexpr swap_ranges_result<_Iter1, _Iter2>
946  operator()(_Iter1 __first1, _Sent1 __last1,
947  _Iter2 __first2, _Sent2 __last2) const
948  {
949  for (; __first1 != __last1 && __first2 != __last2;
950  ++__first1, (void)++__first2)
951  ranges::iter_swap(__first1, __first2);
952  return {std::move(__first1), std::move(__first2)};
953  }
954 
955  template<input_range _Range1, input_range _Range2>
956  requires indirectly_swappable<iterator_t<_Range1>, iterator_t<_Range2>>
957  constexpr swap_ranges_result<borrowed_iterator_t<_Range1>,
958  borrowed_iterator_t<_Range2>>
959  operator()(_Range1&& __r1, _Range2&& __r2) const
960  {
961  return (*this)(ranges::begin(__r1), ranges::end(__r1),
962  ranges::begin(__r2), ranges::end(__r2));
963  }
964  };
965 
966  inline constexpr __swap_ranges_fn swap_ranges{};
967 
968  template<typename _Iter, typename _Out>
969  using unary_transform_result = in_out_result<_Iter, _Out>;
970 
971  template<typename _Iter1, typename _Iter2, typename _Out>
972  struct in_in_out_result
973  {
974  [[no_unique_address]] _Iter1 in1;
975  [[no_unique_address]] _Iter2 in2;
976  [[no_unique_address]] _Out out;
977 
978  template<typename _IIter1, typename _IIter2, typename _OOut>
979  requires convertible_to<const _Iter1&, _IIter1>
980  && convertible_to<const _Iter2&, _IIter2>
981  && convertible_to<const _Out&, _OOut>
982  constexpr
983  operator in_in_out_result<_IIter1, _IIter2, _OOut>() const &
984  { return {in1, in2, out}; }
985 
986  template<typename _IIter1, typename _IIter2, typename _OOut>
987  requires convertible_to<_Iter1, _IIter1>
988  && convertible_to<_Iter2, _IIter2>
989  && convertible_to<_Out, _OOut>
990  constexpr
991  operator in_in_out_result<_IIter1, _IIter2, _OOut>() &&
992  { return {std::move(in1), std::move(in2), std::move(out)}; }
993  };
994 
995  template<typename _Iter1, typename _Iter2, typename _Out>
996  using binary_transform_result = in_in_out_result<_Iter1, _Iter2, _Out>;
997 
998  struct __transform_fn
999  {
1000  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1001  weakly_incrementable _Out,
1002  copy_constructible _Fp, typename _Proj = identity>
1004  indirect_result_t<_Fp&,
1005  projected<_Iter, _Proj>>>
1006  constexpr unary_transform_result<_Iter, _Out>
1007  operator()(_Iter __first1, _Sent __last1, _Out __result,
1008  _Fp __op, _Proj __proj = {}) const
1009  {
1010  for (; __first1 != __last1; ++__first1, (void)++__result)
1011  *__result = std::__invoke(__op, std::__invoke(__proj, *__first1));
1012  return {std::move(__first1), std::move(__result)};
1013  }
1014 
1015  template<input_range _Range, weakly_incrementable _Out,
1016  copy_constructible _Fp, typename _Proj = identity>
1018  indirect_result_t<_Fp&,
1019  projected<iterator_t<_Range>, _Proj>>>
1020  constexpr unary_transform_result<borrowed_iterator_t<_Range>, _Out>
1021  operator()(_Range&& __r, _Out __result, _Fp __op, _Proj __proj = {}) const
1022  {
1023  return (*this)(ranges::begin(__r), ranges::end(__r),
1024  std::move(__result),
1025  std::move(__op), std::move(__proj));
1026  }
1027 
1028  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
1029  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
1030  weakly_incrementable _Out, copy_constructible _Fp,
1031  typename _Proj1 = identity, typename _Proj2 = identity>
1033  indirect_result_t<_Fp&,
1034  projected<_Iter1, _Proj1>,
1035  projected<_Iter2, _Proj2>>>
1036  constexpr binary_transform_result<_Iter1, _Iter2, _Out>
1037  operator()(_Iter1 __first1, _Sent1 __last1,
1038  _Iter2 __first2, _Sent2 __last2,
1039  _Out __result, _Fp __binary_op,
1040  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
1041  {
1042  for (; __first1 != __last1 && __first2 != __last2;
1043  ++__first1, (void)++__first2, ++__result)
1044  *__result = std::__invoke(__binary_op,
1045  std::__invoke(__proj1, *__first1),
1046  std::__invoke(__proj2, *__first2));
1047  return {std::move(__first1), std::move(__first2), std::move(__result)};
1048  }
1049 
1050  template<input_range _Range1, input_range _Range2,
1052  typename _Proj1 = identity, typename _Proj2 = identity>
1054  indirect_result_t<_Fp&,
1055  projected<iterator_t<_Range1>, _Proj1>,
1056  projected<iterator_t<_Range2>, _Proj2>>>
1057  constexpr binary_transform_result<borrowed_iterator_t<_Range1>,
1058  borrowed_iterator_t<_Range2>, _Out>
1059  operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Fp __binary_op,
1060  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
1061  {
1062  return (*this)(ranges::begin(__r1), ranges::end(__r1),
1063  ranges::begin(__r2), ranges::end(__r2),
1064  std::move(__result), std::move(__binary_op),
1065  std::move(__proj1), std::move(__proj2));
1066  }
1067  };
1068 
1069  inline constexpr __transform_fn transform{};
1070 
1071  struct __replace_fn
1072  {
1073  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1074  typename _Proj = identity,
1075  typename _Tp1 _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
1076  typename _Tp2 _GLIBCXX26_DEF_VAL_T(iter_value_t<_Iter>)>
1077  requires indirectly_writable<_Iter, const _Tp2&>
1078  && indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>,
1079  const _Tp1*>
1080  constexpr _Iter
1081  operator()(_Iter __first, _Sent __last,
1082  const _Tp1& __old_value, const _Tp2& __new_value,
1083  _Proj __proj = {}) const
1084  {
1085  for (; __first != __last; ++__first)
1086  if (std::__invoke(__proj, *__first) == __old_value)
1087  *__first = __new_value;
1088  return __first;
1089  }
1090 
1091  template<input_range _Range, typename _Proj = identity,
1092  typename _Tp1
1093  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj),
1094  typename _Tp2 _GLIBCXX26_DEF_VAL_T(range_value_t<_Range>)>
1095  requires indirectly_writable<iterator_t<_Range>, const _Tp2&>
1096  && indirect_binary_predicate<ranges::equal_to,
1097  projected<iterator_t<_Range>, _Proj>,
1098  const _Tp1*>
1099  constexpr borrowed_iterator_t<_Range>
1100  operator()(_Range&& __r,
1101  const _Tp1& __old_value, const _Tp2& __new_value,
1102  _Proj __proj = {}) const
1103  {
1104  return (*this)(ranges::begin(__r), ranges::end(__r),
1105  __old_value, __new_value, std::move(__proj));
1106  }
1107  };
1108 
1109  inline constexpr __replace_fn replace{};
1110 
1111  struct __replace_if_fn
1112  {
1113  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1114  typename _Proj = identity,
1115  typename _Tp _GLIBCXX26_DEF_VAL_T(iter_value_t<_Iter>),
1116  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
1117  requires indirectly_writable<_Iter, const _Tp&>
1118  constexpr _Iter
1119  operator()(_Iter __first, _Sent __last,
1120  _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
1121  {
1122  for (; __first != __last; ++__first)
1123  if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
1124  *__first = __new_value;
1125  return std::move(__first);
1126  }
1127 
1128  template<input_range _Range, typename _Proj = identity,
1129  typename _Tp
1130  _GLIBCXX26_DEF_VAL_T(range_value_t<_Range>),
1131  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
1132  _Pred>
1133  requires indirectly_writable<iterator_t<_Range>, const _Tp&>
1134  constexpr borrowed_iterator_t<_Range>
1135  operator()(_Range&& __r,
1136  _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
1137  {
1138  return (*this)(ranges::begin(__r), ranges::end(__r),
1139  std::move(__pred), __new_value, std::move(__proj));
1140  }
1141  };
1142 
1143  inline constexpr __replace_if_fn replace_if{};
1144 
1145  template<typename _Iter, typename _Out>
1146  using replace_copy_result = in_out_result<_Iter, _Out>;
1147 
1148  struct __replace_copy_fn
1149  {
1150  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1151  typename _Out, typename _Proj = identity,
1152  typename _Tp1 _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
1153  typename _Tp2 _GLIBCXX26_DEF_VAL_T(iter_value_t<_Out>)>
1154  requires indirectly_copyable<_Iter, _Out>
1155  && indirect_binary_predicate<ranges::equal_to,
1156  projected<_Iter, _Proj>, const _Tp1*>
1157  && output_iterator<_Out, const _Tp2&>
1158  constexpr replace_copy_result<_Iter, _Out>
1159  operator()(_Iter __first, _Sent __last, _Out __result,
1160  const _Tp1& __old_value, const _Tp2& __new_value,
1161  _Proj __proj = {}) const
1162  {
1163  for (; __first != __last; ++__first, (void)++__result)
1164  if (std::__invoke(__proj, *__first) == __old_value)
1165  *__result = __new_value;
1166  else
1167  *__result = *__first;
1168  return {std::move(__first), std::move(__result)};
1169  }
1170 
1171  template<input_range _Range, typename _Out,
1172  typename _Proj = identity,
1173  typename _Tp1
1174  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj),
1175  typename _Tp2 _GLIBCXX26_DEF_VAL_T(iter_value_t<_Out>)>
1176  requires indirectly_copyable<iterator_t<_Range>, _Out>
1177  && indirect_binary_predicate<ranges::equal_to,
1178  projected<iterator_t<_Range>, _Proj>,
1179  const _Tp1*>
1180  && output_iterator<_Out, const _Tp2&>
1181  constexpr replace_copy_result<borrowed_iterator_t<_Range>, _Out>
1182  operator()(_Range&& __r, _Out __result,
1183  const _Tp1& __old_value, const _Tp2& __new_value,
1184  _Proj __proj = {}) const
1185  {
1186  return (*this)(ranges::begin(__r), ranges::end(__r),
1187  std::move(__result), __old_value,
1188  __new_value, std::move(__proj));
1189  }
1190  };
1191 
1192  inline constexpr __replace_copy_fn replace_copy{};
1193 
1194  template<typename _Iter, typename _Out>
1195  using replace_copy_if_result = in_out_result<_Iter, _Out>;
1196 
1197  struct __replace_copy_if_fn
1198  {
1199  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1200  typename _Out,
1201  typename _Tp _GLIBCXX26_DEF_VAL_T(iter_value_t<_Out>),
1202  typename _Proj = identity,
1203  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
1204  requires indirectly_copyable<_Iter, _Out>
1205  && output_iterator<_Out, const _Tp&>
1206  constexpr replace_copy_if_result<_Iter, _Out>
1207  operator()(_Iter __first, _Sent __last, _Out __result,
1208  _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
1209  {
1210  for (; __first != __last; ++__first, (void)++__result)
1211  if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
1212  *__result = __new_value;
1213  else
1214  *__result = *__first;
1215  return {std::move(__first), std::move(__result)};
1216  }
1217 
1218  template<input_range _Range,
1219  typename _Out,
1220  typename _Tp _GLIBCXX26_DEF_VAL_T(iter_value_t<_Out>),
1221  typename _Proj = identity,
1222  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
1223  _Pred>
1224  requires indirectly_copyable<iterator_t<_Range>, _Out>
1225  && output_iterator<_Out, const _Tp&>
1226  constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _Out>
1227  operator()(_Range&& __r, _Out __result,
1228  _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
1229  {
1230  return (*this)(ranges::begin(__r), ranges::end(__r),
1231  std::move(__result), std::move(__pred),
1232  __new_value, std::move(__proj));
1233  }
1234  };
1235 
1236  inline constexpr __replace_copy_if_fn replace_copy_if{};
1237 
1238  struct __generate_n_fn
1239  {
1240  template<input_or_output_iterator _Out, copy_constructible _Fp>
1241  requires invocable<_Fp&>
1242  && indirectly_writable<_Out, invoke_result_t<_Fp&>>
1243  constexpr _Out
1244  operator()(_Out __first, iter_difference_t<_Out> __n, _Fp __gen) const
1245  {
1246  for (; __n > 0; --__n, (void)++__first)
1247  *__first = std::__invoke(__gen);
1248  return __first;
1249  }
1250  };
1251 
1252  inline constexpr __generate_n_fn generate_n{};
1253 
1254  struct __generate_fn
1255  {
1256  template<input_or_output_iterator _Out, sentinel_for<_Out> _Sent,
1257  copy_constructible _Fp>
1258  requires invocable<_Fp&>
1259  && indirectly_writable<_Out, invoke_result_t<_Fp&>>
1260  constexpr _Out
1261  operator()(_Out __first, _Sent __last, _Fp __gen) const
1262  {
1263  for (; __first != __last; ++__first)
1264  *__first = std::__invoke(__gen);
1265  return __first;
1266  }
1267 
1268  template<typename _Range, copy_constructible _Fp>
1269  requires invocable<_Fp&> && output_range<_Range, invoke_result_t<_Fp&>>
1270  constexpr borrowed_iterator_t<_Range>
1271  operator()(_Range&& __r, _Fp __gen) const
1272  {
1273  return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__gen));
1274  }
1275  };
1276 
1277  inline constexpr __generate_fn generate{};
1278 
1279  struct __remove_if_fn
1280  {
1281  template<permutable _Iter, sentinel_for<_Iter> _Sent,
1282  typename _Proj = identity,
1283  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
1284  [[nodiscard]] constexpr subrange<_Iter>
1285  operator()(_Iter __first, _Sent __last,
1286  _Pred __pred, _Proj __proj = {}) const
1287  {
1288  __first = ranges::find_if(__first, __last, __pred, __proj);
1289  if (__first == __last)
1290  return {__first, __first};
1291 
1292  auto __result = __first;
1293  ++__first;
1294  for (; __first != __last; ++__first)
1295  if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
1296  {
1297  *__result = ranges::iter_move(__first);
1298  ++__result;
1299  }
1300 
1301  return {__result, __first};
1302  }
1303 
1304  template<forward_range _Range, typename _Proj = identity,
1305  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
1306  _Pred>
1307  requires permutable<iterator_t<_Range>>
1308  [[nodiscard]] constexpr borrowed_subrange_t<_Range>
1309  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
1310  {
1311  return (*this)(ranges::begin(__r), ranges::end(__r),
1312  std::move(__pred), std::move(__proj));
1313  }
1314  };
1315 
1316  inline constexpr __remove_if_fn remove_if{};
1317 
1318  struct __remove_fn
1319  {
1320  template<permutable _Iter, sentinel_for<_Iter> _Sent,
1321  typename _Proj = identity,
1322  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
1323  requires indirect_binary_predicate<ranges::equal_to,
1324  projected<_Iter, _Proj>,
1325  const _Tp*>
1326  [[nodiscard]] constexpr subrange<_Iter>
1327  operator()(_Iter __first, _Sent __last,
1328  const _Tp& __value, _Proj __proj = {}) const
1329  {
1330  auto __pred = [&] (auto&& __arg) -> bool {
1331  return std::forward<decltype(__arg)>(__arg) == __value;
1332  };
1333  return ranges::remove_if(__first, __last,
1334  std::move(__pred), std::move(__proj));
1335  }
1336 
1337  template<forward_range _Range, typename _Proj = identity,
1338  typename _Tp
1339  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj)>
1340  requires permutable<iterator_t<_Range>>
1341  && indirect_binary_predicate<ranges::equal_to,
1342  projected<iterator_t<_Range>, _Proj>,
1343  const _Tp*>
1344  [[nodiscard]] constexpr borrowed_subrange_t<_Range>
1345  operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
1346  {
1347  return (*this)(ranges::begin(__r), ranges::end(__r),
1348  __value, std::move(__proj));
1349  }
1350  };
1351 
1352  inline constexpr __remove_fn remove{};
1353 
1354  template<typename _Iter, typename _Out>
1355  using remove_copy_if_result = in_out_result<_Iter, _Out>;
1356 
1357  struct __remove_copy_if_fn
1358  {
1359  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1360  weakly_incrementable _Out, typename _Proj = identity,
1361  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
1362  requires indirectly_copyable<_Iter, _Out>
1363  constexpr remove_copy_if_result<_Iter, _Out>
1364  operator()(_Iter __first, _Sent __last, _Out __result,
1365  _Pred __pred, _Proj __proj = {}) const
1366  {
1367  for (; __first != __last; ++__first)
1368  if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
1369  {
1370  *__result = *__first;
1371  ++__result;
1372  }
1373  return {std::move(__first), std::move(__result)};
1374  }
1375 
1376  template<input_range _Range, weakly_incrementable _Out,
1377  typename _Proj = identity,
1378  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
1379  _Pred>
1380  requires indirectly_copyable<iterator_t<_Range>, _Out>
1381  constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _Out>
1382  operator()(_Range&& __r, _Out __result,
1383  _Pred __pred, _Proj __proj = {}) const
1384  {
1385  return (*this)(ranges::begin(__r), ranges::end(__r),
1386  std::move(__result),
1387  std::move(__pred), std::move(__proj));
1388  }
1389  };
1390 
1391  inline constexpr __remove_copy_if_fn remove_copy_if{};
1392 
1393  template<typename _Iter, typename _Out>
1394  using remove_copy_result = in_out_result<_Iter, _Out>;
1395 
1396  struct __remove_copy_fn
1397  {
1398  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1399  weakly_incrementable _Out, typename _Proj = identity,
1400  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
1401  requires indirectly_copyable<_Iter, _Out>
1402  && indirect_binary_predicate<ranges::equal_to,
1403  projected<_Iter, _Proj>,
1404  const _Tp*>
1405  constexpr remove_copy_result<_Iter, _Out>
1406  operator()(_Iter __first, _Sent __last, _Out __result,
1407  const _Tp& __value, _Proj __proj = {}) const
1408  {
1409  for (; __first != __last; ++__first)
1410  if (!(std::__invoke(__proj, *__first) == __value))
1411  {
1412  *__result = *__first;
1413  ++__result;
1414  }
1415  return {std::move(__first), std::move(__result)};
1416  }
1417 
1418  template<input_range _Range, weakly_incrementable _Out,
1419  typename _Proj = identity,
1420  typename _Tp
1421  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj)>
1422  requires indirectly_copyable<iterator_t<_Range>, _Out>
1423  && indirect_binary_predicate<ranges::equal_to,
1424  projected<iterator_t<_Range>, _Proj>,
1425  const _Tp*>
1426  constexpr remove_copy_result<borrowed_iterator_t<_Range>, _Out>
1427  operator()(_Range&& __r, _Out __result,
1428  const _Tp& __value, _Proj __proj = {}) const
1429  {
1430  return (*this)(ranges::begin(__r), ranges::end(__r),
1431  std::move(__result), __value, std::move(__proj));
1432  }
1433  };
1434 
1435  inline constexpr __remove_copy_fn remove_copy{};
1436 
1437  struct __unique_fn
1438  {
1439  template<permutable _Iter, sentinel_for<_Iter> _Sent,
1440  typename _Proj = identity,
1441  indirect_equivalence_relation<
1442  projected<_Iter, _Proj>> _Comp = ranges::equal_to>
1443  [[nodiscard]] constexpr subrange<_Iter>
1444  operator()(_Iter __first, _Sent __last,
1445  _Comp __comp = {}, _Proj __proj = {}) const
1446  {
1447  __first = ranges::adjacent_find(__first, __last, __comp, __proj);
1448  if (__first == __last)
1449  return {__first, __first};
1450 
1451  auto __dest = __first;
1452  ++__first;
1453  while (++__first != __last)
1454  if (!std::__invoke(__comp,
1455  std::__invoke(__proj, *__dest),
1456  std::__invoke(__proj, *__first)))
1457  *++__dest = ranges::iter_move(__first);
1458  return {++__dest, __first};
1459  }
1460 
1461  template<forward_range _Range, typename _Proj = identity,
1462  indirect_equivalence_relation<
1463  projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
1464  requires permutable<iterator_t<_Range>>
1465  [[nodiscard]] constexpr borrowed_subrange_t<_Range>
1466  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
1467  {
1468  return (*this)(ranges::begin(__r), ranges::end(__r),
1469  std::move(__comp), std::move(__proj));
1470  }
1471  };
1472 
1473  inline constexpr __unique_fn unique{};
1474 
1475  namespace __detail
1476  {
1477  template<typename _Out, typename _Tp>
1478  concept __can_reread_output = input_iterator<_Out>
1479  && same_as<_Tp, iter_value_t<_Out>>;
1480  }
1481 
1482  template<typename _Iter, typename _Out>
1483  using unique_copy_result = in_out_result<_Iter, _Out>;
1484 
1485  struct __unique_copy_fn
1486  {
1487  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1488  weakly_incrementable _Out, typename _Proj = identity,
1489  indirect_equivalence_relation<
1490  projected<_Iter, _Proj>> _Comp = ranges::equal_to>
1491  requires indirectly_copyable<_Iter, _Out>
1492  && (forward_iterator<_Iter>
1493  || __detail::__can_reread_output<_Out, iter_value_t<_Iter>>
1494  || indirectly_copyable_storable<_Iter, _Out>)
1495  constexpr unique_copy_result<_Iter, _Out>
1496  operator()(_Iter __first, _Sent __last, _Out __result,
1497  _Comp __comp = {}, _Proj __proj = {}) const
1498  {
1499  if (__first == __last)
1500  return {std::move(__first), std::move(__result)};
1501 
1502  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1503  // 4269. unique_copy passes arguments to its predicate backwards
1504 
1505  // TODO: perform a closer comparison with reference implementations
1506  if constexpr (forward_iterator<_Iter>)
1507  {
1508  auto __next = __first;
1509  *__result = *__next;
1510  while (++__next != __last)
1511  if (!std::__invoke(__comp,
1512  std::__invoke(__proj, *__first),
1513  std::__invoke(__proj, *__next)))
1514  {
1515  __first = __next;
1516  *++__result = *__first;
1517  }
1518  return {__next, std::move(++__result)};
1519  }
1520  else if constexpr (__detail::__can_reread_output<_Out, iter_value_t<_Iter>>)
1521  {
1522  *__result = *__first;
1523  while (++__first != __last)
1524  if (!std::__invoke(__comp,
1525  std::__invoke(__proj, *__result),
1526  std::__invoke(__proj, *__first)))
1527  *++__result = *__first;
1528  return {std::move(__first), std::move(++__result)};
1529  }
1530  else // indirectly_copyable_storable<_Iter, _Out>
1531  {
1532  iter_value_t<_Iter> __value(*__first);
1533  *__result = __value;
1534  while (++__first != __last)
1535  {
1536  if (!(bool)std::__invoke(__comp,
1537  std::__invoke(__proj, __value),
1538  std::__invoke(__proj, *__first)))
1539  {
1540  __value = *__first;
1541  *++__result = __value;
1542  }
1543  }
1544  return {std::move(__first), std::move(++__result)};
1545  }
1546  }
1547 
1548  template<input_range _Range,
1549  weakly_incrementable _Out, typename _Proj = identity,
1550  indirect_equivalence_relation<
1551  projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
1552  requires indirectly_copyable<iterator_t<_Range>, _Out>
1553  && (forward_iterator<iterator_t<_Range>>
1554  || __detail::__can_reread_output<_Out, range_value_t<_Range>>
1555  || indirectly_copyable_storable<iterator_t<_Range>, _Out>)
1556  constexpr unique_copy_result<borrowed_iterator_t<_Range>, _Out>
1557  operator()(_Range&& __r, _Out __result,
1558  _Comp __comp = {}, _Proj __proj = {}) const
1559  {
1560  return (*this)(ranges::begin(__r), ranges::end(__r),
1561  std::move(__result),
1562  std::move(__comp), std::move(__proj));
1563  }
1564  };
1565 
1566  inline constexpr __unique_copy_fn unique_copy{};
1567 
1568  struct __reverse_fn
1569  {
1570  template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent>
1571  requires permutable<_Iter>
1572  constexpr _Iter
1573  operator()(_Iter __first, _Sent __last) const
1574  {
1575  auto __i = ranges::next(__first, __last);
1576  auto __tail = __i;
1577 
1578  if constexpr (random_access_iterator<_Iter>)
1579  {
1580  if (__first != __last)
1581  {
1582  --__tail;
1583  while (__first < __tail)
1584  {
1585  ranges::iter_swap(__first, __tail);
1586  ++__first;
1587  --__tail;
1588  }
1589  }
1590  return __i;
1591  }
1592  else
1593  {
1594  for (;;)
1595  if (__first == __tail || __first == --__tail)
1596  break;
1597  else
1598  {
1599  ranges::iter_swap(__first, __tail);
1600  ++__first;
1601  }
1602  return __i;
1603  }
1604  }
1605 
1606  template<bidirectional_range _Range>
1607  requires permutable<iterator_t<_Range>>
1608  constexpr borrowed_iterator_t<_Range>
1609  operator()(_Range&& __r) const
1610  {
1611  return (*this)(ranges::begin(__r), ranges::end(__r));
1612  }
1613  };
1614 
1615  inline constexpr __reverse_fn reverse{};
1616 
1617  template<typename _Iter, typename _Out>
1618  using reverse_copy_result = in_out_result<_Iter, _Out>;
1619 
1620  struct __reverse_copy_fn
1621  {
1622  template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
1623  weakly_incrementable _Out>
1624  requires indirectly_copyable<_Iter, _Out>
1625  constexpr reverse_copy_result<_Iter, _Out>
1626  operator()(_Iter __first, _Sent __last, _Out __result) const
1627  {
1628  auto __i = ranges::next(__first, __last);
1629  auto __tail = __i;
1630  while (__first != __tail)
1631  {
1632  --__tail;
1633  *__result = *__tail;
1634  ++__result;
1635  }
1636  return {__i, std::move(__result)};
1637  }
1638 
1639  template<bidirectional_range _Range, weakly_incrementable _Out>
1640  requires indirectly_copyable<iterator_t<_Range>, _Out>
1641  constexpr reverse_copy_result<borrowed_iterator_t<_Range>, _Out>
1642  operator()(_Range&& __r, _Out __result) const
1643  {
1644  return (*this)(ranges::begin(__r), ranges::end(__r),
1645  std::move(__result));
1646  }
1647  };
1648 
1649  inline constexpr __reverse_copy_fn reverse_copy{};
1650 
1651  struct __rotate_fn
1652  {
1653  template<permutable _Iter, sentinel_for<_Iter> _Sent>
1654  constexpr subrange<_Iter>
1655  operator()(_Iter __first, _Iter __middle, _Sent __last) const
1656  {
1657  auto __lasti = ranges::next(__first, __last);
1658  if (__first == __middle)
1659  return {__lasti, __lasti};
1660  if (__last == __middle)
1661  return {std::move(__first), std::move(__lasti)};
1662 
1663  if constexpr (random_access_iterator<_Iter>)
1664  {
1665  auto __n = __lasti - __first;
1666  auto __k = __middle - __first;
1667 
1668  if (__k == __n - __k)
1669  {
1670  ranges::swap_ranges(__first, __middle, __middle, __middle + __k);
1671  return {std::move(__middle), std::move(__lasti)};
1672  }
1673 
1674  auto __p = __first;
1675  auto __ret = __first + (__lasti - __middle);
1676 
1677  for (;;)
1678  {
1679  if (__k < __n - __k)
1680  {
1681  // TODO: is_pod is deprecated, but this condition is
1682  // consistent with the STL implementation.
1683  if constexpr (__is_pod(iter_value_t<_Iter>))
1684  if (__k == 1)
1685  {
1686  auto __mid = ranges::next(__p, __n - 1);
1687  auto __end = ranges::next(__mid);
1688  iter_value_t<_Iter> __t(ranges::iter_move(__p));
1689  ranges::move(ranges::next(__p), __end, __p);
1690  *__mid = std::move(__t);
1691  return {std::move(__ret), std::move(__lasti)};
1692  }
1693  auto __q = __p + __k;
1694  for (decltype(__n) __i = 0; __i < __n - __k; ++ __i)
1695  {
1696  ranges::iter_swap(__p, __q);
1697  ++__p;
1698  ++__q;
1699  }
1700  __n %= __k;
1701  if (__n == 0)
1702  return {std::move(__ret), std::move(__lasti)};
1703  ranges::swap(__n, __k);
1704  __k = __n - __k;
1705  }
1706  else
1707  {
1708  __k = __n - __k;
1709  // TODO: is_pod is deprecated, but this condition is
1710  // consistent with the STL implementation.
1711  if constexpr (__is_pod(iter_value_t<_Iter>))
1712  if (__k == 1)
1713  {
1714  auto __mid = ranges::next(__p, __n - 1);
1715  auto __end = ranges::next(__mid);
1716  iter_value_t<_Iter> __t(ranges::iter_move(__mid));
1717  ranges::move_backward(__p, __mid, __end);
1718  *__p = std::move(__t);
1719  return {std::move(__ret), std::move(__lasti)};
1720  }
1721  auto __q = __p + __n;
1722  __p = __q - __k;
1723  for (decltype(__n) __i = 0; __i < __n - __k; ++ __i)
1724  {
1725  --__p;
1726  --__q;
1727  ranges::iter_swap(__p, __q);
1728  }
1729  __n %= __k;
1730  if (__n == 0)
1731  return {std::move(__ret), std::move(__lasti)};
1732  std::swap(__n, __k);
1733  }
1734  }
1735  }
1736  else if constexpr (bidirectional_iterator<_Iter>)
1737  {
1738  auto __tail = __lasti;
1739 
1740  ranges::reverse(__first, __middle);
1741  ranges::reverse(__middle, __tail);
1742 
1743  while (__first != __middle && __middle != __tail)
1744  {
1745  ranges::iter_swap(__first, --__tail);
1746  ++__first;
1747  }
1748 
1749  if (__first == __middle)
1750  {
1751  ranges::reverse(__middle, __tail);
1752  return {std::move(__tail), std::move(__lasti)};
1753  }
1754  else
1755  {
1756  ranges::reverse(__first, __middle);
1757  return {std::move(__first), std::move(__lasti)};
1758  }
1759  }
1760  else
1761  {
1762  auto __first2 = __middle;
1763  do
1764  {
1765  ranges::iter_swap(__first, __first2);
1766  ++__first;
1767  ++__first2;
1768  if (__first == __middle)
1769  __middle = __first2;
1770  } while (__first2 != __last);
1771 
1772  auto __ret = __first;
1773 
1774  __first2 = __middle;
1775 
1776  while (__first2 != __last)
1777  {
1778  ranges::iter_swap(__first, __first2);
1779  ++__first;
1780  ++__first2;
1781  if (__first == __middle)
1782  __middle = __first2;
1783  else if (__first2 == __last)
1784  __first2 = __middle;
1785  }
1786  return {std::move(__ret), std::move(__lasti)};
1787  }
1788  }
1789 
1790  template<forward_range _Range>
1791  requires permutable<iterator_t<_Range>>
1792  constexpr borrowed_subrange_t<_Range>
1793  operator()(_Range&& __r, iterator_t<_Range> __middle) const
1794  {
1795  return (*this)(ranges::begin(__r), std::move(__middle),
1796  ranges::end(__r));
1797  }
1798  };
1799 
1800  inline constexpr __rotate_fn rotate{};
1801 
1802  template<typename _Iter, typename _Out>
1803  using rotate_copy_result = in_out_result<_Iter, _Out>;
1804 
1805  struct __rotate_copy_fn
1806  {
1807  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
1808  weakly_incrementable _Out>
1809  requires indirectly_copyable<_Iter, _Out>
1810  constexpr rotate_copy_result<_Iter, _Out>
1811  operator()(_Iter __first, _Iter __middle, _Sent __last,
1812  _Out __result) const
1813  {
1814  auto __copy1 = ranges::copy(__middle,
1815  std::move(__last),
1816  std::move(__result));
1817  auto __copy2 = ranges::copy(std::move(__first),
1818  std::move(__middle),
1819  std::move(__copy1.out));
1820  return { std::move(__copy1.in), std::move(__copy2.out) };
1821  }
1822 
1823  template<forward_range _Range, weakly_incrementable _Out>
1824  requires indirectly_copyable<iterator_t<_Range>, _Out>
1825  constexpr rotate_copy_result<borrowed_iterator_t<_Range>, _Out>
1826  operator()(_Range&& __r, iterator_t<_Range> __middle, _Out __result) const
1827  {
1828  return (*this)(ranges::begin(__r), std::move(__middle),
1829  ranges::end(__r), std::move(__result));
1830  }
1831  };
1832 
1833  inline constexpr __rotate_copy_fn rotate_copy{};
1834 
1835  struct __sample_fn
1836  {
1837  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
1838  weakly_incrementable _Out, typename _Gen>
1839  requires (forward_iterator<_Iter> || random_access_iterator<_Out>)
1840  && indirectly_copyable<_Iter, _Out>
1841  && uniform_random_bit_generator<remove_reference_t<_Gen>>
1842  _Out
1843  operator()(_Iter __first, _Sent __last, _Out __out,
1844  iter_difference_t<_Iter> __n, _Gen&& __g) const
1845  {
1846  // FIXME: Correctly handle integer-class difference types.
1847  if constexpr (forward_iterator<_Iter>)
1848  {
1849  using _Size = iter_difference_t<_Iter>;
1850  using __distrib_type = uniform_int_distribution<_Size>;
1851  using __param_type = typename __distrib_type::param_type;
1852  using _USize = __detail::__make_unsigned_like_t<_Size>;
1853  using __uc_type = common_type_t<decltype(__g()), _USize>;
1854 
1855  if (__first == __last)
1856  return __out;
1857 
1858  __distrib_type __d{};
1859  _Size __unsampled_sz = ranges::distance(__first, __last);
1860  __n = std::min(__n, __unsampled_sz);
1861 
1862  // If possible, we use __gen_two_uniform_ints to efficiently produce
1863  // two random numbers using a single distribution invocation:
1864 
1865  const __uc_type __urngrange = __g.max() - __g.min();
1866  if (__urngrange / __uc_type(__unsampled_sz) >= __uc_type(__unsampled_sz))
1867  // I.e. (__urngrange >= __unsampled_sz * __unsampled_sz) but without
1868  // wrapping issues.
1869  {
1870  while (__n != 0 && __unsampled_sz >= 2)
1871  {
1872  const pair<_Size, _Size> __p =
1873  __gen_two_uniform_ints(__unsampled_sz, __unsampled_sz - 1, __g);
1874 
1875  --__unsampled_sz;
1876  if (__p.first < __n)
1877  {
1878  *__out = *__first;
1879  ++__out;
1880  --__n;
1881  }
1882 
1883  ++__first;
1884 
1885  if (__n == 0) break;
1886 
1887  --__unsampled_sz;
1888  if (__p.second < __n)
1889  {
1890  *__out = *__first;
1891  ++__out;
1892  --__n;
1893  }
1894 
1895  ++__first;
1896  }
1897  }
1898 
1899  // The loop above is otherwise equivalent to this one-at-a-time version:
1900 
1901  for (; __n != 0; ++__first)
1902  if (__d(__g, __param_type{0, --__unsampled_sz}) < __n)
1903  {
1904  *__out = *__first;
1905  ++__out;
1906  --__n;
1907  }
1908  return __out;
1909  }
1910  else
1911  {
1912  using __distrib_type
1913  = uniform_int_distribution<iter_difference_t<_Iter>>;
1914  using __param_type = typename __distrib_type::param_type;
1915  __distrib_type __d{};
1916  iter_difference_t<_Iter> __sample_sz = 0;
1917  while (__first != __last && __sample_sz != __n)
1918  {
1919  __out[__sample_sz++] = *__first;
1920  ++__first;
1921  }
1922  for (auto __pop_sz = __sample_sz; __first != __last;
1923  ++__first, (void) ++__pop_sz)
1924  {
1925  const auto __k = __d(__g, __param_type{0, __pop_sz});
1926  if (__k < __n)
1927  __out[__k] = *__first;
1928  }
1929  return __out + iter_difference_t<_Out>(__sample_sz);
1930  }
1931  }
1932 
1933  template<input_range _Range, weakly_incrementable _Out, typename _Gen>
1934  requires (forward_range<_Range> || random_access_iterator<_Out>)
1935  && indirectly_copyable<iterator_t<_Range>, _Out>
1936  && uniform_random_bit_generator<remove_reference_t<_Gen>>
1937  _Out
1938  operator()(_Range&& __r, _Out __out,
1939  range_difference_t<_Range> __n, _Gen&& __g) const
1940  {
1941  return (*this)(ranges::begin(__r), ranges::end(__r),
1942  std::move(__out), __n,
1943  std::forward<_Gen>(__g));
1944  }
1945  };
1946 
1947  inline constexpr __sample_fn sample{};
1948 
1949  struct __shuffle_fn
1950  {
1951  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
1952  typename _Gen>
1953  requires permutable<_Iter>
1954  && uniform_random_bit_generator<remove_reference_t<_Gen>>
1955  _Iter
1956  operator()(_Iter __first, _Sent __last, _Gen&& __g) const
1957  {
1958  // FIXME: Correctly handle integer-class difference types.
1959  if (__first == __last)
1960  return __first;
1961 
1962  using _DistanceType = iter_difference_t<_Iter>;
1963  using __ud_type = __detail::__make_unsigned_like_t<_DistanceType>;
1964  using __distr_type = std::uniform_int_distribution<__ud_type>;
1965  using __p_type = typename __distr_type::param_type;
1966  using __uc_type = common_type_t<decltype(__g()), __ud_type>;
1967 
1968  if constexpr (sized_sentinel_for<_Sent, _Iter>)
1969  {
1970  const __uc_type __urngrange = __g.max() - __g.min();
1971  const __uc_type __urange = __uc_type(__last - __first);
1972 
1973  if (__urngrange / __urange >= __urange)
1974  // I.e. (__urngrange >= __urange * __urange) but without wrap issues.
1975  {
1976  _Iter __i = ranges::next(__first);
1977 
1978  // Since we know the range isn't empty, an even number of elements
1979  // means an uneven number of elements /to swap/, in which case we
1980  // do the first one up front:
1981 
1982  if ((__urange % 2) == 0)
1983  {
1984  __distr_type __d{0, 1};
1985  ranges::iter_swap(__i++, ranges::next(__first, __d(__g)));
1986  }
1987 
1988  // Now we know that __last - __i is even, so we do the rest in pairs,
1989  // using a single distribution invocation to produce swap positions
1990  // for two successive elements at a time:
1991 
1992  while (__i != __last)
1993  {
1994  const __uc_type __swap_range = __uc_type(__i - __first) + 1;
1995 
1996  const pair<_DistanceType, _DistanceType> __pospos =
1997  __gen_two_uniform_ints(__swap_range, __swap_range + 1, __g);
1998 
1999  ranges::iter_swap(__i++, ranges::next(__first, __pospos.first));
2000  ranges::iter_swap(__i++, ranges::next(__first, __pospos.second));
2001  }
2002 
2003  return __i;
2004  }
2005  }
2006 
2007  __distr_type __d;
2008 
2009  _Iter __i = ranges::next(__first);
2010  for (; __i != __last; ++__i)
2011  ranges::iter_swap(__i,
2012  ranges::next(__first,
2013  __d(__g, __p_type(0, __i - __first))));
2014 
2015  return __i;
2016  }
2017 
2018  template<random_access_range _Range, typename _Gen>
2019  requires permutable<iterator_t<_Range>>
2020  && uniform_random_bit_generator<remove_reference_t<_Gen>>
2021  borrowed_iterator_t<_Range>
2022  operator()(_Range&& __r, _Gen&& __g) const
2023  {
2024  if constexpr (sized_range<_Range>
2025  && !sized_sentinel_for<sentinel_t<_Range>,
2026  iterator_t<_Range>>)
2027  return (*this)(ranges::begin(__r),
2028  ranges::begin(__r) + ranges::distance(__r),
2029  std::forward<_Gen>(__g));
2030  else
2031  return (*this)(ranges::begin(__r), ranges::end(__r),
2032  std::forward<_Gen>(__g));
2033  }
2034  };
2035 
2036  inline constexpr __shuffle_fn shuffle{};
2037 
2038  namespace __detail
2039  {
2040  template<typename _Iter, typename _Comp>
2041  constexpr void
2042  __push_heap(_Iter __first,
2043  iter_difference_t<_Iter> __holeIndex,
2044  iter_difference_t<_Iter> __topIndex,
2045  iter_value_t<_Iter> __value,
2046  _Comp __comp)
2047  {
2048  auto __parent = (__holeIndex - 1) / 2;
2049  while (__holeIndex > __topIndex
2050  && __comp(*(__first + __parent), __value))
2051  {
2052  *(__first + __holeIndex) = ranges::iter_move(__first + __parent);
2053  __holeIndex = __parent;
2054  __parent = (__holeIndex - 1) / 2;
2055  }
2056  *(__first + __holeIndex) = std::move(__value);
2057  }
2058  } // namespace __detail
2059 
2060  struct __push_heap_fn
2061  {
2062  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2063  typename _Comp = ranges::less, typename _Proj = identity>
2064  requires sortable<_Iter, _Comp, _Proj>
2065  constexpr _Iter
2066  operator()(_Iter __first, _Sent __last,
2067  _Comp __comp = {}, _Proj __proj = {}) const
2068  {
2069  if constexpr (!same_as<_Iter, _Sent>)
2070  return (*this)(__first, ranges::next(__first, __last),
2071  std::move(__comp), std::move(__proj));
2072  else
2073  {
2074  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
2075  iter_value_t<_Iter> __value(ranges::iter_move(ranges::prev(__last)));
2076  __detail::__push_heap(__first, (__last - __first) - 1,
2077  0, std::move(__value), __comp_proj);
2078  return __last;
2079  }
2080  }
2081 
2082  template<random_access_range _Range,
2083  typename _Comp = ranges::less, typename _Proj = identity>
2084  requires sortable<iterator_t<_Range>, _Comp, _Proj>
2085  constexpr borrowed_iterator_t<_Range>
2086  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2087  {
2088  return (*this)(ranges::begin(__r), ranges::end(__r),
2089  std::move(__comp), std::move(__proj));
2090  }
2091  };
2092 
2093  inline constexpr __push_heap_fn push_heap{};
2094 
2095  namespace __detail
2096  {
2097  template<typename _Iter, typename _Comp>
2098  constexpr void
2099  __adjust_heap(_Iter __first,
2100  iter_difference_t<_Iter> __holeIndex,
2101  iter_difference_t<_Iter> __len,
2102  iter_value_t<_Iter> __value,
2103  _Comp __comp)
2104  {
2105  auto __topIndex = __holeIndex;
2106  auto __secondChild = __holeIndex;
2107  while (__secondChild < (__len - 1) / 2)
2108  {
2109  __secondChild = 2 * (__secondChild + 1);
2110  if (__comp(*(__first + __secondChild),
2111  *(__first + (__secondChild - 1))))
2112  __secondChild--;
2113  *(__first + __holeIndex) = ranges::iter_move(__first + __secondChild);
2114  __holeIndex = __secondChild;
2115  }
2116  if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
2117  {
2118  __secondChild = 2 * (__secondChild + 1);
2119  *(__first + __holeIndex) = ranges::iter_move(__first + (__secondChild - 1));
2120  __holeIndex = __secondChild - 1;
2121  }
2122  __detail::__push_heap(__first, __holeIndex, __topIndex,
2123  std::move(__value), __comp);
2124  }
2125 
2126  template<typename _Iter, typename _Comp>
2127  constexpr void
2128  __pop_heap(_Iter __first, _Iter __last, _Iter __result, _Comp __comp)
2129  {
2130  iter_value_t<_Iter> __value = ranges::iter_move(__result);
2131  *__result = ranges::iter_move(__first);
2132  __detail::__adjust_heap(__first, 0, __last - __first,
2133  std::move(__value), __comp);
2134  }
2135  } // namespace __detail
2136 
2137  struct __pop_heap_fn
2138  {
2139  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2140  typename _Comp = ranges::less, typename _Proj = identity>
2141  requires sortable<_Iter, _Comp, _Proj>
2142  constexpr _Iter
2143  operator()(_Iter __first, _Sent __last,
2144  _Comp __comp = {}, _Proj __proj = {}) const
2145  {
2146  if constexpr (!same_as<_Iter, _Sent>)
2147  return (*this)(__first, ranges::next(__first, __last),
2148  std::move(__comp), std::move(__proj));
2149  else
2150  {
2151  if (__last - __first > 1)
2152  {
2153  auto __back = ranges::prev(__last);
2154  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
2155  __detail::__pop_heap(__first, __back, __back, __comp_proj);
2156  }
2157  return __last;
2158  }
2159  }
2160 
2161  template<random_access_range _Range,
2162  typename _Comp = ranges::less, typename _Proj = identity>
2163  requires sortable<iterator_t<_Range>, _Comp, _Proj>
2164  constexpr borrowed_iterator_t<_Range>
2165  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2166  {
2167  return (*this)(ranges::begin(__r), ranges::end(__r),
2168  std::move(__comp), std::move(__proj));
2169  }
2170  };
2171 
2172  inline constexpr __pop_heap_fn pop_heap{};
2173 
2174  struct __make_heap_fn
2175  {
2176  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2177  typename _Comp = ranges::less, typename _Proj = identity>
2178  requires sortable<_Iter, _Comp, _Proj>
2179  constexpr _Iter
2180  operator()(_Iter __first, _Sent __last,
2181  _Comp __comp = {}, _Proj __proj = {}) const
2182  {
2183  if constexpr (!same_as<_Iter, _Sent>)
2184  return (*this)(__first, ranges::next(__first, __last),
2185  std::move(__comp), std::move(__proj));
2186  else
2187  {
2188  const auto __len = __last - __first;
2189  if (__len < 2)
2190  return __last;
2191 
2192  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
2193  auto __parent = (__len - 2) / 2;
2194  while (true)
2195  {
2196  iter_value_t<_Iter> __value = ranges::iter_move(__first + __parent);
2197  __detail::__adjust_heap(__first, __parent, __len,
2198  std::move(__value),
2199  __comp_proj);
2200  if (__parent == 0)
2201  break;
2202  __parent--;
2203  }
2204  return __last;
2205  }
2206  }
2207 
2208  template<random_access_range _Range,
2209  typename _Comp = ranges::less, typename _Proj = identity>
2210  requires sortable<iterator_t<_Range>, _Comp, _Proj>
2211  constexpr borrowed_iterator_t<_Range>
2212  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2213  {
2214  return (*this)(ranges::begin(__r), ranges::end(__r),
2215  std::move(__comp), std::move(__proj));
2216  }
2217  };
2218 
2219  inline constexpr __make_heap_fn make_heap{};
2220 
2221  struct __sort_heap_fn
2222  {
2223  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2224  typename _Comp = ranges::less, typename _Proj = identity>
2225  requires sortable<_Iter, _Comp, _Proj>
2226  constexpr _Iter
2227  operator()(_Iter __first, _Sent __last,
2228  _Comp __comp = {}, _Proj __proj = {}) const
2229  {
2230  if constexpr (!same_as<_Iter, _Sent>)
2231  return (*this)(__first, ranges::next(__first, __last),
2232  std::move(__comp), std::move(__proj));
2233  else
2234  {
2235  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
2236  _Iter __ret = __last;
2237  while (__last - __first > 1)
2238  {
2239  --__last;
2240  __detail::__pop_heap(__first, __last, __last, __comp_proj);
2241  }
2242  return __ret;
2243  }
2244  }
2245 
2246  template<random_access_range _Range,
2247  typename _Comp = ranges::less, typename _Proj = identity>
2248  requires sortable<iterator_t<_Range>, _Comp, _Proj>
2249  constexpr borrowed_iterator_t<_Range>
2250  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2251  {
2252  return (*this)(ranges::begin(__r), ranges::end(__r),
2253  std::move(__comp), std::move(__proj));
2254  }
2255  };
2256 
2257  inline constexpr __sort_heap_fn sort_heap{};
2258 
2259  struct __is_heap_until_fn
2260  {
2261  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2262  typename _Proj = identity,
2263  indirect_strict_weak_order<projected<_Iter, _Proj>>
2264  _Comp = ranges::less>
2265  constexpr _Iter
2266  operator()(_Iter __first, _Sent __last,
2267  _Comp __comp = {}, _Proj __proj = {}) const
2268  {
2269  iter_difference_t<_Iter> __n = ranges::distance(__first, __last);
2270  iter_difference_t<_Iter> __parent = 0, __child = 1;
2271  for (; __child < __n; ++__child)
2272  if (std::__invoke(__comp,
2273  std::__invoke(__proj, *(__first + __parent)),
2274  std::__invoke(__proj, *(__first + __child))))
2275  return __first + __child;
2276  else if ((__child & 1) == 0)
2277  ++__parent;
2278 
2279  return __first + __n;
2280  }
2281 
2282  template<random_access_range _Range,
2283  typename _Proj = identity,
2284  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
2285  _Comp = ranges::less>
2286  constexpr borrowed_iterator_t<_Range>
2287  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2288  {
2289  return (*this)(ranges::begin(__r), ranges::end(__r),
2290  std::move(__comp), std::move(__proj));
2291  }
2292  };
2293 
2294  inline constexpr __is_heap_until_fn is_heap_until{};
2295 
2296  struct __is_heap_fn
2297  {
2298  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2299  typename _Proj = identity,
2300  indirect_strict_weak_order<projected<_Iter, _Proj>>
2301  _Comp = ranges::less>
2302  constexpr bool
2303  operator()(_Iter __first, _Sent __last,
2304  _Comp __comp = {}, _Proj __proj = {}) const
2305  {
2306  return (__last
2307  == ranges::is_heap_until(__first, __last,
2308  std::move(__comp),
2309  std::move(__proj)));
2310  }
2311 
2312  template<random_access_range _Range,
2313  typename _Proj = identity,
2314  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
2315  _Comp = ranges::less>
2316  constexpr bool
2317  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2318  {
2319  return (*this)(ranges::begin(__r), ranges::end(__r),
2320  std::move(__comp), std::move(__proj));
2321  }
2322  };
2323 
2324  inline constexpr __is_heap_fn is_heap{};
2325 
2326  namespace __detail
2327  {
2328  template<typename _Iter, typename _Comp>
2329  constexpr void
2330  __move_median_to_first(_Iter __result, _Iter __a, _Iter __b, _Iter __c,
2331  _Comp __comp)
2332  {
2333  if (__comp(*__a, *__b))
2334  {
2335  if (__comp(*__b, *__c))
2336  ranges::iter_swap(__result, __b);
2337  else if (__comp(*__a, *__c))
2338  ranges::iter_swap(__result, __c);
2339  else
2340  ranges::iter_swap(__result, __a);
2341  }
2342  else if (__comp(*__a, *__c))
2343  ranges::iter_swap(__result, __a);
2344  else if (__comp(*__b, *__c))
2345  ranges::iter_swap(__result, __c);
2346  else
2347  ranges::iter_swap(__result, __b);
2348  }
2349 
2350  template<typename _Iter, typename _Comp>
2351  constexpr void
2352  __unguarded_linear_insert(_Iter __last, _Comp __comp)
2353  {
2354  iter_value_t<_Iter> __val = ranges::iter_move(__last);
2355  _Iter __next = __last;
2356  --__next;
2357  while (__comp(__val, *__next))
2358  {
2359  *__last = ranges::iter_move(__next);
2360  __last = __next;
2361  --__next;
2362  }
2363  *__last = std::move(__val);
2364  }
2365 
2366  template<typename _Iter, typename _Comp>
2367  constexpr void
2368  __insertion_sort(_Iter __first, _Iter __last, _Comp __comp)
2369  {
2370  if (__first == __last)
2371  return;
2372 
2373  for (_Iter __i = ranges::next(__first); __i != __last; ++__i)
2374  {
2375  if (__comp(*__i, *__first))
2376  {
2377  iter_value_t<_Iter> __val = ranges::iter_move(__i);
2378  ranges::move_backward(__first, __i, ranges::next(__i));
2379  *__first = std::move(__val);
2380  }
2381  else
2382  __detail::__unguarded_linear_insert(__i, __comp);
2383  }
2384  }
2385 
2386  template<typename _Iter, typename _Comp>
2387  constexpr void
2388  __unguarded_insertion_sort(_Iter __first, _Iter __last, _Comp __comp)
2389  {
2390  for (_Iter __i = __first; __i != __last; ++__i)
2391  __detail::__unguarded_linear_insert(__i, __comp);
2392  }
2393 
2394  inline constexpr int __sort_threshold = 16;
2395 
2396  template<typename _Iter, typename _Comp>
2397  constexpr void
2398  __final_insertion_sort(_Iter __first, _Iter __last, _Comp __comp)
2399  {
2400  constexpr iter_difference_t<_Iter> __threshold = __sort_threshold;
2401  if (__last - __first > __threshold)
2402  {
2403  __detail::__insertion_sort(__first, __first + __threshold, __comp);
2404  __detail::__unguarded_insertion_sort(__first + __threshold, __last,
2405  __comp);
2406  }
2407  else
2408  __detail::__insertion_sort(__first, __last, __comp);
2409  }
2410 
2411  template<typename _Iter, typename _Comp>
2412  constexpr _Iter
2413  __unguarded_partition(_Iter __first, _Iter __last, _Iter __pivot, _Comp __comp)
2414  {
2415  while (true)
2416  {
2417  while (__comp(*__first, *__pivot))
2418  ++__first;
2419  --__last;
2420  while (__comp(*__pivot, *__last))
2421  --__last;
2422  if (!(__first < __last))
2423  return __first;
2424  ranges::iter_swap(__first, __last);
2425  ++__first;
2426  }
2427  }
2428 
2429  template<typename _Iter, typename _Comp>
2430  constexpr _Iter
2431  __unguarded_partition_pivot(_Iter __first, _Iter __last, _Comp __comp)
2432  {
2433  _Iter __mid = __first + (__last - __first) / 2;
2434  __detail::__move_median_to_first(__first, ranges::next(__first), __mid,
2435  ranges::prev(__last), __comp);
2436  return __detail::__unguarded_partition(ranges::next(__first), __last,
2437  __first, __comp);
2438  }
2439 
2440  template<typename _Iter, typename _Comp>
2441  constexpr void
2442  __heap_select(_Iter __first, _Iter __middle, _Iter __last, _Comp __comp)
2443  {
2444  ranges::make_heap(__first, __middle, __comp);
2445  for (_Iter __i = __middle; __i < __last; ++__i)
2446  if (__comp(*__i, *__first))
2447  __detail::__pop_heap(__first, __middle, __i, __comp);
2448  }
2449 
2450  template<typename _Iter, typename _Comp>
2451  constexpr void
2452  __partial_sort(_Iter __first, _Iter __middle, _Iter __last, _Comp __comp)
2453  {
2454  __detail::__heap_select(__first, __middle, __last, __comp);
2455  ranges::sort_heap(__first, __middle, __comp);
2456  }
2457 
2458  template<typename _Iter, typename _Comp>
2459  constexpr void
2460  __introsort_loop(_Iter __first, _Iter __last, unsigned __depth_limit, _Comp __comp)
2461  {
2462  while (__last - __first > __sort_threshold)
2463  {
2464  if (__depth_limit == 0)
2465  {
2466  __detail::__partial_sort(__first, __last, __last, __comp);
2467  return;
2468  }
2469  --__depth_limit;
2470  _Iter __cut = __detail::__unguarded_partition_pivot(__first, __last, __comp);
2471  __detail::__introsort_loop(__cut, __last, __depth_limit, __comp);
2472  __last = __cut;
2473  }
2474  }
2475  } // namespace __detail
2476 
2477  struct __sort_fn
2478  {
2479  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2480  typename _Comp = ranges::less, typename _Proj = identity>
2481  requires sortable<_Iter, _Comp, _Proj>
2482  constexpr _Iter
2483  operator()(_Iter __first, _Sent __last,
2484  _Comp __comp = {}, _Proj __proj = {}) const
2485  {
2486  if constexpr (!same_as<_Iter, _Sent>)
2487  return (*this)(__first, ranges::next(__first, __last),
2488  std::move(__comp), std::move(__proj));
2489  else
2490  {
2491  if (__first != __last)
2492  {
2493  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
2494  auto __n = __detail::__to_unsigned_like(__last - __first);
2495  unsigned __depth_limit = (std::__bit_width(__n) - 1) * 2;
2496  __detail::__introsort_loop(__first, __last, __depth_limit, __comp_proj);
2497  __detail::__final_insertion_sort(__first, __last, __comp_proj);
2498  }
2499  return __last;
2500  }
2501  }
2502 
2503  template<random_access_range _Range,
2504  typename _Comp = ranges::less, typename _Proj = identity>
2505  requires sortable<iterator_t<_Range>, _Comp, _Proj>
2506  constexpr borrowed_iterator_t<_Range>
2507  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2508  {
2509  return (*this)(ranges::begin(__r), ranges::end(__r),
2510  std::move(__comp), std::move(__proj));
2511  }
2512  };
2513 
2514  inline constexpr __sort_fn sort{};
2515 
2516  namespace __detail
2517  {
2518  // This is a helper function for the __merge_sort_loop routines.
2519  template<typename _Iter, typename _Out, typename _Comp>
2520  _Out
2521  __move_merge(_Iter __first1, _Iter __last1,
2522  _Iter __first2, _Iter __last2,
2523  _Out __result, _Comp __comp)
2524  {
2525  while (__first1 != __last1 && __first2 != __last2)
2526  {
2527  if (__comp(*__first2, *__first1))
2528  {
2529  *__result = ranges::iter_move(__first2);
2530  ++__first2;
2531  }
2532  else
2533  {
2534  *__result = ranges::iter_move(__first1);
2535  ++__first1;
2536  }
2537  ++__result;
2538  }
2539  return ranges::move(__first2, __last2,
2540  ranges::move(__first1, __last1, __result).out).out;
2541  }
2542 
2543  template<typename _Iter, typename _Out, typename _Distance, typename _Comp>
2544  void
2545  __merge_sort_loop(_Iter __first, _Iter __last, _Out __result,
2546  _Distance __step_size, _Comp __comp)
2547  {
2548  const _Distance __two_step = 2 * __step_size;
2549 
2550  while (__last - __first >= __two_step)
2551  {
2552  __result = __detail::__move_merge(__first, __first + __step_size,
2553  __first + __step_size,
2554  __first + __two_step,
2555  __result, __comp);
2556  __first += __two_step;
2557  }
2558  __step_size = ranges::min(_Distance(__last - __first), __step_size);
2559 
2560  __detail::__move_merge(__first, __first + __step_size,
2561  __first + __step_size, __last, __result, __comp);
2562  }
2563 
2564  template<typename _Iter, typename _Distance, typename _Compare>
2565  constexpr void
2566  __chunk_insertion_sort(_Iter __first, _Iter __last,
2567  _Distance __chunk_size, _Compare __comp)
2568  {
2569  while (__last - __first >= __chunk_size)
2570  {
2571  __detail::__insertion_sort(__first, __first + __chunk_size, __comp);
2572  __first += __chunk_size;
2573  }
2574  __detail::__insertion_sort(__first, __last, __comp);
2575  }
2576 
2577  template<typename _Iter, typename _Pointer, typename _Comp>
2578  void
2579  __merge_sort_with_buffer(_Iter __first, _Iter __last,
2580  _Pointer __buffer, _Comp __comp)
2581  {
2582  using _Distance = iter_difference_t<_Iter>;
2583 
2584  const _Distance __len = __last - __first;
2585  const _Pointer __buffer_last = __buffer + ptrdiff_t(__len);
2586 
2587  constexpr int __chunk_size = 7;
2588  _Distance __step_size = __chunk_size;
2589  __detail::__chunk_insertion_sort(__first, __last, __step_size, __comp);
2590 
2591  while (__step_size < __len)
2592  {
2593  __detail::__merge_sort_loop(__first, __last, __buffer,
2594  __step_size, __comp);
2595  __step_size *= 2;
2596  __detail::__merge_sort_loop(__buffer, __buffer_last, __first,
2597  ptrdiff_t(__step_size), __comp);
2598  __step_size *= 2;
2599  }
2600  }
2601 
2602  template<typename _Iter, typename _Pointer, typename _Comp>
2603  void
2604  __merge_adaptive(_Iter __first, _Iter __middle, _Iter __last,
2605  iter_difference_t<_Iter> __len1,
2606  iter_difference_t<_Iter> __len2,
2607  _Pointer __buffer, _Comp __comp); // defined near inplace_merge
2608 
2609  template<typename _Iter, typename _Distance, typename _Pointer, typename _Comp>
2610  void
2611  __merge_adaptive_resize(_Iter __first, _Iter __middle, _Iter __last,
2612  _Distance __len1, _Distance __len2,
2613  _Pointer __buffer, _Distance __buffer_size,
2614  _Comp __comp); // defined near inplace_merge
2615 
2616  template<typename _Iter, typename _Distance, typename _Comp>
2617  constexpr void
2618  __merge_without_buffer(_Iter __first, _Iter __middle, _Iter __last,
2619  _Distance __len1, _Distance __len2,
2620  _Comp __comp); // defined near inplace_merge
2621 
2622  template<typename _Iter, typename _Pointer, typename _Comp>
2623  void
2624  __stable_sort_adaptive(_Iter __first, _Iter __middle, _Iter __last,
2625  _Pointer __buffer, _Comp __comp)
2626  {
2627  __detail::__merge_sort_with_buffer(__first, __middle, __buffer, __comp);
2628  __detail::__merge_sort_with_buffer(__middle, __last, __buffer, __comp);
2629 
2630  __detail::__merge_adaptive(__first, __middle, __last,
2631  __middle - __first, __last - __middle,
2632  __buffer, __comp);
2633  }
2634 
2635  template<typename _Iter, typename _Pointer, typename _Distance, typename _Comp>
2636  void
2637  __stable_sort_adaptive_resize(_Iter __first, _Iter __last,
2638  _Pointer __buffer, _Distance __buffer_size,
2639  _Comp __comp)
2640  {
2641  const _Distance __len = (__last - __first + 1) / 2;
2642  const _Iter __middle = __first + __len;
2643  if (__len > __buffer_size)
2644  {
2645  __detail::__stable_sort_adaptive_resize(__first, __middle, __buffer,
2646  __buffer_size, __comp);
2647  __detail::__stable_sort_adaptive_resize(__middle, __last, __buffer,
2648  __buffer_size, __comp);
2649  __detail::__merge_adaptive_resize(__first, __middle, __last,
2650  _Distance(__middle - __first),
2651  _Distance(__last - __middle),
2652  __buffer, __buffer_size,
2653  __comp);
2654  }
2655  else
2656  __detail::__stable_sort_adaptive(__first, __middle, __last,
2657  __buffer, __comp);
2658  }
2659 
2660  template<typename _Iter, typename _Comp>
2661  constexpr void
2662  __inplace_stable_sort(_Iter __first, _Iter __last, _Comp __comp)
2663  {
2664  if (__last - __first < 15)
2665  {
2666  __detail::__insertion_sort(__first, __last, __comp);
2667  return;
2668  }
2669  _Iter __middle = __first + (__last - __first) / 2;
2670  __detail::__inplace_stable_sort(__first, __middle, __comp);
2671  __detail::__inplace_stable_sort(__middle, __last, __comp);
2672  __detail::__merge_without_buffer(__first, __middle, __last,
2673  __middle - __first,
2674  __last - __middle,
2675  __comp);
2676  }
2677  } // namespace __detail
2678 
2679  struct __stable_sort_fn
2680  {
2681  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2682  typename _Comp = ranges::less, typename _Proj = identity>
2683  requires sortable<_Iter, _Comp, _Proj>
2684  _GLIBCXX26_CONSTEXPR
2685  _Iter
2686  operator()(_Iter __first, _Sent __last,
2687  _Comp __comp = {}, _Proj __proj = {}) const
2688  {
2689  if constexpr (!same_as<_Iter, _Sent>)
2690  return (*this)(__first, ranges::next(__first, __last),
2691  std::move(__comp), std::move(__proj));
2692  else
2693  {
2694  using _DistanceType = iter_difference_t<_Iter>;
2695 
2696  if (__first == __last)
2697  return __last;
2698 
2699  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
2700 
2701 #if _GLIBCXX_HOSTED
2702 # if __glibcxx_constexpr_algorithms >= 202306L // >= C++26
2703  if consteval {
2704  __detail::__inplace_stable_sort(__first, __last, __comp_proj);
2705  return __last;
2706  }
2707 # endif
2708 
2709  using _TmpBuf = _Temporary_buffer<_Iter, iter_value_t<_Iter>>;
2710  // __stable_sort_adaptive sorts the range in two halves,
2711  // so the buffer only needs to fit half the range at once.
2712  _TmpBuf __buf(__first, ptrdiff_t((__last - __first + 1) / 2));
2713 
2714  if (__buf._M_requested_size() == __buf.size()) [[likely]]
2715  __detail::__stable_sort_adaptive(__first,
2716  __first + _DistanceType(__buf.size()),
2717  __last, __buf.begin(), __comp_proj);
2718  else if (__buf.begin() == nullptr) [[unlikely]]
2719  __detail::__inplace_stable_sort(__first, __last, __comp_proj);
2720  else
2721  __detail::__stable_sort_adaptive_resize(__first, __last, __buf.begin(),
2722  _DistanceType(__buf.size()),
2723  __comp_proj);
2724 #else
2725  __detail::__inplace_stable_sort(__first, __last, __comp_proj);
2726 #endif
2727  return __last;
2728  }
2729  }
2730 
2731  template<random_access_range _Range,
2732  typename _Comp = ranges::less, typename _Proj = identity>
2733  requires sortable<iterator_t<_Range>, _Comp, _Proj>
2734  _GLIBCXX26_CONSTEXPR
2735  borrowed_iterator_t<_Range>
2736  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2737  {
2738  return (*this)(ranges::begin(__r), ranges::end(__r),
2739  std::move(__comp), std::move(__proj));
2740  }
2741  };
2742 
2743  inline constexpr __stable_sort_fn stable_sort{};
2744 
2745  struct __partial_sort_fn
2746  {
2747  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2748  typename _Comp = ranges::less, typename _Proj = identity>
2749  requires sortable<_Iter, _Comp, _Proj>
2750  constexpr _Iter
2751  operator()(_Iter __first, _Iter __middle, _Sent __last,
2752  _Comp __comp = {}, _Proj __proj = {}) const
2753  {
2754  if (__first == __middle)
2755  return ranges::next(__first, __last);
2756 
2757  ranges::make_heap(__first, __middle, __comp, __proj);
2758  auto __i = __middle;
2759  for (; __i != __last; ++__i)
2760  if (std::__invoke(__comp,
2761  std::__invoke(__proj, *__i),
2762  std::__invoke(__proj, *__first)))
2763  {
2764  ranges::pop_heap(__first, __middle, __comp, __proj);
2765  ranges::iter_swap(std::prev(__middle), __i);
2766  ranges::push_heap(__first, __middle, __comp, __proj);
2767  }
2768  ranges::sort_heap(__first, __middle, __comp, __proj);
2769 
2770  return __i;
2771  }
2772 
2773  template<random_access_range _Range,
2774  typename _Comp = ranges::less, typename _Proj = identity>
2775  requires sortable<iterator_t<_Range>, _Comp, _Proj>
2776  constexpr borrowed_iterator_t<_Range>
2777  operator()(_Range&& __r, iterator_t<_Range> __middle,
2778  _Comp __comp = {}, _Proj __proj = {}) const
2779  {
2780  return (*this)(ranges::begin(__r), std::move(__middle),
2781  ranges::end(__r),
2782  std::move(__comp), std::move(__proj));
2783  }
2784  };
2785 
2786  inline constexpr __partial_sort_fn partial_sort{};
2787 
2788  template<typename _Iter, typename _Out>
2789  using partial_sort_copy_result = in_out_result<_Iter, _Out>;
2790 
2791  struct __partial_sort_copy_fn
2792  {
2793  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
2794  random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
2795  typename _Comp = ranges::less,
2796  typename _Proj1 = identity, typename _Proj2 = identity>
2797  requires indirectly_copyable<_Iter1, _Iter2>
2798  && sortable<_Iter2, _Comp, _Proj2>
2799  && indirect_strict_weak_order<_Comp,
2800  projected<_Iter1, _Proj1>,
2801  projected<_Iter2, _Proj2>>
2802  constexpr partial_sort_copy_result<_Iter1, _Iter2>
2803  operator()(_Iter1 __first, _Sent1 __last,
2804  _Iter2 __result_first, _Sent2 __result_last,
2805  _Comp __comp = {},
2806  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2807  {
2808  if (__result_first == __result_last)
2809  {
2810  // TODO: Eliminating the variable __lasti triggers an ICE.
2811  auto __lasti = ranges::next(std::move(__first),
2812  std::move(__last));
2813  return {std::move(__lasti), std::move(__result_first)};
2814  }
2815 
2816  auto __result_real_last = __result_first;
2817  while (__first != __last && __result_real_last != __result_last)
2818  {
2819  *__result_real_last = *__first;
2820  ++__result_real_last;
2821  ++__first;
2822  }
2823 
2824  ranges::make_heap(__result_first, __result_real_last, __comp, __proj2);
2825  for (; __first != __last; ++__first)
2826  if (std::__invoke(__comp,
2827  std::__invoke(__proj1, *__first),
2828  std::__invoke(__proj2, *__result_first)))
2829  {
2830  ranges::pop_heap(__result_first, __result_real_last,
2831  __comp, __proj2);
2832  *ranges::prev(__result_real_last) = *__first;
2833  ranges::push_heap(__result_first, __result_real_last,
2834  __comp, __proj2);
2835  }
2836  ranges::sort_heap(__result_first, __result_real_last, __comp, __proj2);
2837 
2838  return {std::move(__first), std::move(__result_real_last)};
2839  }
2840 
2841  template<input_range _Range1, random_access_range _Range2,
2842  typename _Comp = ranges::less,
2843  typename _Proj1 = identity, typename _Proj2 = identity>
2844  requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>>
2845  && sortable<iterator_t<_Range2>, _Comp, _Proj2>
2846  && indirect_strict_weak_order<_Comp,
2847  projected<iterator_t<_Range1>, _Proj1>,
2848  projected<iterator_t<_Range2>, _Proj2>>
2849  constexpr partial_sort_copy_result<borrowed_iterator_t<_Range1>,
2850  borrowed_iterator_t<_Range2>>
2851  operator()(_Range1&& __r, _Range2&& __out, _Comp __comp = {},
2852  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
2853  {
2854  return (*this)(ranges::begin(__r), ranges::end(__r),
2855  ranges::begin(__out), ranges::end(__out),
2856  std::move(__comp),
2857  std::move(__proj1), std::move(__proj2));
2858  }
2859  };
2860 
2861  inline constexpr __partial_sort_copy_fn partial_sort_copy{};
2862 
2863  struct __is_sorted_until_fn
2864  {
2865  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
2866  typename _Proj = identity,
2867  indirect_strict_weak_order<projected<_Iter, _Proj>>
2868  _Comp = ranges::less>
2869  [[nodiscard]] constexpr _Iter
2870  operator()(_Iter __first, _Sent __last,
2871  _Comp __comp = {}, _Proj __proj = {}) const
2872  {
2873  if (__first == __last)
2874  return __first;
2875 
2876  auto __next = __first;
2877  for (++__next; __next != __last; __first = __next, (void)++__next)
2878  if (std::__invoke(__comp,
2879  std::__invoke(__proj, *__next),
2880  std::__invoke(__proj, *__first)))
2881  return __next;
2882  return __next;
2883  }
2884 
2885  template<forward_range _Range, typename _Proj = identity,
2886  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
2887  _Comp = ranges::less>
2888  [[nodiscard]] constexpr borrowed_iterator_t<_Range>
2889  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2890  {
2891  return (*this)(ranges::begin(__r), ranges::end(__r),
2892  std::move(__comp), std::move(__proj));
2893  }
2894  };
2895 
2896  inline constexpr __is_sorted_until_fn is_sorted_until{};
2897 
2898  struct __is_sorted_fn
2899  {
2900  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
2901  typename _Proj = identity,
2902  indirect_strict_weak_order<projected<_Iter, _Proj>>
2903  _Comp = ranges::less>
2904  [[nodiscard]] constexpr bool
2905  operator()(_Iter __first, _Sent __last,
2906  _Comp __comp = {}, _Proj __proj = {}) const
2907  {
2908  if (__first == __last)
2909  return true;
2910 
2911  auto __next = __first;
2912  for (++__next; __next != __last; __first = __next, (void)++__next)
2913  if (std::__invoke(__comp,
2914  std::__invoke(__proj, *__next),
2915  std::__invoke(__proj, *__first)))
2916  return false;
2917  return true;
2918  }
2919 
2920  template<forward_range _Range, typename _Proj = identity,
2921  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
2922  _Comp = ranges::less>
2923  [[nodiscard]] constexpr bool
2924  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
2925  {
2926  return (*this)(ranges::begin(__r), ranges::end(__r),
2927  std::move(__comp), std::move(__proj));
2928  }
2929  };
2930 
2931  inline constexpr __is_sorted_fn is_sorted{};
2932 
2933  namespace __detail
2934  {
2935  template<typename _Iter, typename _Comp>
2936  constexpr void
2937  __introselect(_Iter __first, _Iter __nth, _Iter __last,
2938  iter_difference_t<_Iter> __depth_limit, _Comp __comp)
2939  {
2940  while (__last - __first > 3)
2941  {
2942  if (__depth_limit == 0)
2943  {
2944  __detail::__heap_select(__first, ranges::next(__nth), __last,
2945  __comp);
2946  // Place the nth largest element in its final position.
2947  ranges::iter_swap(__first, __nth);
2948  return;
2949  }
2950  --__depth_limit;
2951  _Iter __cut = __detail::__unguarded_partition_pivot(__first, __last, __comp);
2952  if (__cut <= __nth)
2953  __first = __cut;
2954  else
2955  __last = __cut;
2956  }
2957  __detail::__insertion_sort(__first, __last, __comp);
2958  }
2959  } // namespace __detail
2960 
2961  struct __nth_element_fn
2962  {
2963  template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent,
2964  typename _Comp = ranges::less, typename _Proj = identity>
2965  requires sortable<_Iter, _Comp, _Proj>
2966  constexpr _Iter
2967  operator()(_Iter __first, _Iter __nth, _Sent __last,
2968  _Comp __comp = {}, _Proj __proj = {}) const
2969  {
2970  if constexpr (!same_as<_Iter, _Sent>)
2971  return (*this)(__first, __nth, ranges::next(__first, __last),
2972  std::move(__comp), std::move(__proj));
2973  else
2974  {
2975  if (__first == __last || __nth == __last)
2976  return __last;
2977 
2978  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
2979  auto __n = __detail::__to_unsigned_like(__last - __first);
2980  __detail::__introselect(__first, __nth, __last,
2981  std::__bit_width(__n) * 2,
2982  __comp_proj);
2983  return __last;
2984  }
2985  }
2986 
2987  template<random_access_range _Range,
2988  typename _Comp = ranges::less, typename _Proj = identity>
2989  requires sortable<iterator_t<_Range>, _Comp, _Proj>
2990  constexpr borrowed_iterator_t<_Range>
2991  operator()(_Range&& __r, iterator_t<_Range> __nth,
2992  _Comp __comp = {}, _Proj __proj = {}) const
2993  {
2994  return (*this)(ranges::begin(__r), std::move(__nth),
2995  ranges::end(__r), std::move(__comp), std::move(__proj));
2996  }
2997  };
2998 
2999  inline constexpr __nth_element_fn nth_element{};
3000 
3001  struct __lower_bound_fn
3002  {
3003  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
3004  typename _Proj = identity,
3005  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
3006  indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
3007  _Comp = ranges::less>
3008  [[nodiscard]] constexpr _Iter
3009  operator()(_Iter __first, _Sent __last,
3010  const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
3011  {
3012  auto __len = ranges::distance(__first, __last);
3013 
3014  while (__len > 0)
3015  {
3016  auto __half = __len / 2;
3017  auto __middle = __first;
3018  ranges::advance(__middle, __half);
3019  if (std::__invoke(__comp, std::__invoke(__proj, *__middle), __value))
3020  {
3021  __first = __middle;
3022  ++__first;
3023  __len = __len - __half - 1;
3024  }
3025  else
3026  __len = __half;
3027  }
3028  return __first;
3029  }
3030 
3031  template<forward_range _Range,
3032  typename _Proj = identity,
3033  typename _Tp
3034  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj),
3035  indirect_strict_weak_order<const _Tp*,
3036  projected<iterator_t<_Range>, _Proj>>
3037  _Comp = ranges::less>
3038  [[nodiscard]] constexpr borrowed_iterator_t<_Range>
3039  operator()(_Range&& __r,
3040  const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
3041  {
3042  return (*this)(ranges::begin(__r), ranges::end(__r),
3043  __value, std::move(__comp), std::move(__proj));
3044  }
3045  };
3046 
3047  inline constexpr __lower_bound_fn lower_bound{};
3048 
3049  struct __upper_bound_fn
3050  {
3051  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
3052  typename _Proj = identity,
3053  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
3054  indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
3055  _Comp = ranges::less>
3056  [[nodiscard]] constexpr _Iter
3057  operator()(_Iter __first, _Sent __last,
3058  const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
3059  {
3060  auto __len = ranges::distance(__first, __last);
3061 
3062  while (__len > 0)
3063  {
3064  auto __half = __len / 2;
3065  auto __middle = __first;
3066  ranges::advance(__middle, __half);
3067  if (std::__invoke(__comp, __value, std::__invoke(__proj, *__middle)))
3068  __len = __half;
3069  else
3070  {
3071  __first = __middle;
3072  ++__first;
3073  __len = __len - __half - 1;
3074  }
3075  }
3076  return __first;
3077  }
3078 
3079  template<forward_range _Range,
3080  typename _Proj = identity,
3081  typename _Tp
3082  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj),
3083  indirect_strict_weak_order<const _Tp*,
3084  projected<iterator_t<_Range>, _Proj>>
3085  _Comp = ranges::less>
3086  [[nodiscard]] constexpr borrowed_iterator_t<_Range>
3087  operator()(_Range&& __r,
3088  const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
3089  {
3090  return (*this)(ranges::begin(__r), ranges::end(__r),
3091  __value, std::move(__comp), std::move(__proj));
3092  }
3093  };
3094 
3095  inline constexpr __upper_bound_fn upper_bound{};
3096 
3097  struct __equal_range_fn
3098  {
3099  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
3100  typename _Proj = identity,
3101  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
3102  indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
3103  _Comp = ranges::less>
3104  [[nodiscard]] constexpr subrange<_Iter>
3105  operator()(_Iter __first, _Sent __last,
3106  const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
3107  {
3108  auto __len = ranges::distance(__first, __last);
3109 
3110  while (__len > 0)
3111  {
3112  auto __half = __len / 2;
3113  auto __middle = __first;
3114  ranges::advance(__middle, __half);
3115  if (std::__invoke(__comp,
3116  std::__invoke(__proj, *__middle),
3117  __value))
3118  {
3119  __first = __middle;
3120  ++__first;
3121  __len = __len - __half - 1;
3122  }
3123  else if (std::__invoke(__comp,
3124  __value,
3125  std::__invoke(__proj, *__middle)))
3126  __len = __half;
3127  else
3128  {
3129  auto __left
3130  = ranges::lower_bound(__first, __middle,
3131  __value, __comp, __proj);
3132  ranges::advance(__first, __len);
3133  auto __right
3134  = ranges::upper_bound(++__middle, __first,
3135  __value, __comp, __proj);
3136  return {__left, __right};
3137  }
3138  }
3139  return {__first, __first};
3140  }
3141 
3142  template<forward_range _Range,
3143  typename _Proj = identity,
3144  typename _Tp
3145  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj),
3146  indirect_strict_weak_order<const _Tp*,
3147  projected<iterator_t<_Range>, _Proj>>
3148  _Comp = ranges::less>
3149  [[nodiscard]] constexpr borrowed_subrange_t<_Range>
3150  operator()(_Range&& __r, const _Tp& __value,
3151  _Comp __comp = {}, _Proj __proj = {}) const
3152  {
3153  return (*this)(ranges::begin(__r), ranges::end(__r),
3154  __value, std::move(__comp), std::move(__proj));
3155  }
3156  };
3157 
3158  inline constexpr __equal_range_fn equal_range{};
3159 
3160  struct __binary_search_fn
3161  {
3162  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
3163  typename _Proj = identity,
3164  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj),
3165  indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
3166  _Comp = ranges::less>
3167  [[nodiscard]] constexpr bool
3168  operator()(_Iter __first, _Sent __last,
3169  const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
3170  {
3171  auto __i = ranges::lower_bound(__first, __last, __value, __comp, __proj);
3172  if (__i == __last)
3173  return false;
3174  return !(bool)std::__invoke(__comp, __value,
3175  std::__invoke(__proj, *__i));
3176  }
3177 
3178  template<forward_range _Range,
3179  typename _Proj = identity,
3180  typename _Tp
3181  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj),
3182  indirect_strict_weak_order<const _Tp*,
3183  projected<iterator_t<_Range>, _Proj>>
3184  _Comp = ranges::less>
3185  [[nodiscard]] constexpr bool
3186  operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {},
3187  _Proj __proj = {}) const
3188  {
3189  return (*this)(ranges::begin(__r), ranges::end(__r),
3190  __value, std::move(__comp), std::move(__proj));
3191  }
3192  };
3193 
3194  inline constexpr __binary_search_fn binary_search{};
3195 
3196  struct __is_partitioned_fn
3197  {
3198  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
3199  typename _Proj = identity,
3200  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
3201  [[nodiscard]] constexpr bool
3202  operator()(_Iter __first, _Sent __last,
3203  _Pred __pred, _Proj __proj = {}) const
3204  {
3205  __first = ranges::find_if_not(std::move(__first), __last,
3206  __pred, __proj);
3207  if (__first == __last)
3208  return true;
3209  ++__first;
3210  return ranges::none_of(std::move(__first), std::move(__last),
3211  std::move(__pred), std::move(__proj));
3212  }
3213 
3214  template<input_range _Range, typename _Proj = identity,
3215  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
3216  _Pred>
3217  [[nodiscard]] constexpr bool
3218  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
3219  {
3220  return (*this)(ranges::begin(__r), ranges::end(__r),
3221  std::move(__pred), std::move(__proj));
3222  }
3223  };
3224 
3225  inline constexpr __is_partitioned_fn is_partitioned{};
3226 
3227  struct __partition_fn
3228  {
3229  template<permutable _Iter, sentinel_for<_Iter> _Sent,
3230  typename _Proj = identity,
3231  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
3232  constexpr subrange<_Iter>
3233  operator()(_Iter __first, _Sent __last,
3234  _Pred __pred, _Proj __proj = {}) const
3235  {
3236  if constexpr (bidirectional_iterator<_Iter>)
3237  {
3238  auto __lasti = ranges::next(__first, __last);
3239  auto __tail = __lasti;
3240  for (;;)
3241  {
3242  for (;;)
3243  if (__first == __tail)
3244  return {std::move(__first), std::move(__lasti)};
3245  else if (std::__invoke(__pred,
3246  std::__invoke(__proj, *__first)))
3247  ++__first;
3248  else
3249  break;
3250  --__tail;
3251  for (;;)
3252  if (__first == __tail)
3253  return {std::move(__first), std::move(__lasti)};
3254  else if (!(bool)std::__invoke(__pred,
3255  std::__invoke(__proj, *__tail)))
3256  --__tail;
3257  else
3258  break;
3259  ranges::iter_swap(__first, __tail);
3260  ++__first;
3261  }
3262  }
3263  else
3264  {
3265  if (__first == __last)
3266  return {__first, __first};
3267 
3268  while (std::__invoke(__pred, std::__invoke(__proj, *__first)))
3269  if (++__first == __last)
3270  return {__first, __first};
3271 
3272  auto __next = __first;
3273  while (++__next != __last)
3274  if (std::__invoke(__pred, std::__invoke(__proj, *__next)))
3275  {
3276  ranges::iter_swap(__first, __next);
3277  ++__first;
3278  }
3279 
3280  return {std::move(__first), std::move(__next)};
3281  }
3282  }
3283 
3284  template<forward_range _Range, typename _Proj = identity,
3285  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
3286  _Pred>
3287  requires permutable<iterator_t<_Range>>
3288  constexpr borrowed_subrange_t<_Range>
3289  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
3290  {
3291  return (*this)(ranges::begin(__r), ranges::end(__r),
3292  std::move(__pred), std::move(__proj));
3293  }
3294  };
3295 
3296  inline constexpr __partition_fn partition{};
3297 
3298 #if _GLIBCXX_HOSTED
3299  namespace __detail
3300  {
3301  // Like find_if_not(), but uses and updates a count of the
3302  // remaining range length instead of comparing against an end
3303  // iterator.
3304  template<typename _Iter, typename _Pred, typename _Distance>
3305  constexpr _Iter
3306  __find_if_not_n(_Iter __first, _Distance& __len, _Pred __pred)
3307  {
3308  for (; __len; --__len, (void) ++__first)
3309  if (!__pred(*__first))
3310  break;
3311  return __first;
3312  }
3313 
3314  template<typename _Iter, typename _Sent, typename _Pointer,
3315  typename _Pred, typename _Distance>
3316  constexpr subrange<_Iter>
3317  __stable_partition_adaptive(_Iter __first, _Sent __last,
3318  _Pred __pred, _Distance __len,
3319  _Pointer __buffer,
3320  _Distance __buffer_size)
3321  {
3322  if (__len == 1)
3323  return {__first, ranges::next(__first, 1)};
3324 
3325  if (__len <= __buffer_size)
3326  {
3327  _Iter __result1 = __first;
3328  _Pointer __result2 = __buffer;
3329 
3330  // The precondition guarantees that !__pred(__first), so
3331  // move that element to the buffer before starting the loop.
3332  // This ensures that we only call __pred once per element.
3333  *__result2 = ranges::iter_move(__first);
3334  ++__result2;
3335  ++__first;
3336  for (; __first != __last; ++__first)
3337  if (__pred(*__first))
3338  {
3339  *__result1 = ranges::iter_move(__first);
3340  ++__result1;
3341  }
3342  else
3343  {
3344  *__result2 = ranges::iter_move(__first);
3345  ++__result2;
3346  }
3347 
3348  ranges::move(__buffer, __result2, __result1);
3349  return {__result1, __first};
3350  }
3351 
3352  _Iter __middle = __first;
3353  ranges::advance(__middle, __len / 2);
3354  _Iter __left_split
3355  = __detail::__stable_partition_adaptive(__first, __middle, __pred,
3356  __len / 2, __buffer,
3357  __buffer_size).begin();
3358 
3359  // Advance past true-predicate values to satisfy this
3360  // function's preconditions.
3361  _Distance __right_len = __len - __len / 2;
3362  _Iter __right_split = __detail::__find_if_not_n(__middle, __right_len, __pred);
3363 
3364  if (__right_len)
3365  __right_split
3366  = __detail::__stable_partition_adaptive(__right_split, __last, __pred,
3367  __right_len, __buffer, __buffer_size).begin();
3368 
3369  return ranges::rotate(__left_split, __middle, __right_split);
3370  }
3371  } // namespace __detail
3372 
3373  struct __stable_partition_fn
3374  {
3375  template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
3376  typename _Proj = identity,
3377  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
3378  requires permutable<_Iter>
3379  _GLIBCXX26_CONSTEXPR
3380  subrange<_Iter>
3381  operator()(_Iter __first, _Sent __last,
3382  _Pred __pred, _Proj __proj = {}) const
3383  {
3384  __first = ranges::find_if_not(__first, __last, __pred, __proj);
3385 
3386  if (__first == __last)
3387  return {__first, __first};
3388 
3389  using _DistanceType = iter_difference_t<_Iter>;
3390  const _DistanceType __len = ranges::distance(__first, __last);
3391 
3392  auto __pred_proj = __detail::__make_pred_proj(__pred, __proj);
3393 
3394 #if __glibcxx_constexpr_algorithms >= 202306L // >= C++26
3395  if consteval {
3396  // Simulate a _Temporary_buffer of length 1:
3397  iter_value_t<_Iter> __buf = ranges::iter_move(__first);
3398  *__first = std::move(__buf);
3399  return __detail::__stable_partition_adaptive(__first, __last,
3400  __pred_proj,
3401  __len, &__buf,
3402  _DistanceType(1));
3403  }
3404 #endif
3405 
3406  _Temporary_buffer<_Iter, iter_value_t<_Iter>> __buf(__first, ptrdiff_t(__len));
3407  return __detail::__stable_partition_adaptive(__first, __last,
3408  __pred_proj,
3409  __len, __buf.begin(),
3410  _DistanceType(__buf.size()));
3411  }
3412 
3413  template<bidirectional_range _Range, typename _Proj = identity,
3414  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
3415  _Pred>
3416  requires permutable<iterator_t<_Range>>
3417  _GLIBCXX26_CONSTEXPR
3418  borrowed_subrange_t<_Range>
3419  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
3420  {
3421  return (*this)(ranges::begin(__r), ranges::end(__r),
3422  std::move(__pred), std::move(__proj));
3423  }
3424  };
3425 
3426  inline constexpr __stable_partition_fn stable_partition{};
3427 #endif
3428 
3429  template<typename _Iter, typename _Out1, typename _Out2>
3430  struct in_out_out_result
3431  {
3432  [[no_unique_address]] _Iter in;
3433  [[no_unique_address]] _Out1 out1;
3434  [[no_unique_address]] _Out2 out2;
3435 
3436  template<typename _IIter, typename _OOut1, typename _OOut2>
3437  requires convertible_to<const _Iter&, _IIter>
3438  && convertible_to<const _Out1&, _OOut1>
3439  && convertible_to<const _Out2&, _OOut2>
3440  constexpr
3441  operator in_out_out_result<_IIter, _OOut1, _OOut2>() const &
3442  { return {in, out1, out2}; }
3443 
3444  template<typename _IIter, typename _OOut1, typename _OOut2>
3445  requires convertible_to<_Iter, _IIter>
3446  && convertible_to<_Out1, _OOut1>
3447  && convertible_to<_Out2, _OOut2>
3448  constexpr
3449  operator in_out_out_result<_IIter, _OOut1, _OOut2>() &&
3450  { return {std::move(in), std::move(out1), std::move(out2)}; }
3451  };
3452 
3453  template<typename _Iter, typename _Out1, typename _Out2>
3454  using partition_copy_result = in_out_out_result<_Iter, _Out1, _Out2>;
3455 
3456  struct __partition_copy_fn
3457  {
3458  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
3459  weakly_incrementable _Out1, weakly_incrementable _Out2,
3460  typename _Proj = identity,
3461  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
3462  requires indirectly_copyable<_Iter, _Out1>
3463  && indirectly_copyable<_Iter, _Out2>
3464  constexpr partition_copy_result<_Iter, _Out1, _Out2>
3465  operator()(_Iter __first, _Sent __last,
3466  _Out1 __out_true, _Out2 __out_false,
3467  _Pred __pred, _Proj __proj = {}) const
3468  {
3469  for (; __first != __last; ++__first)
3470  if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
3471  {
3472  *__out_true = *__first;
3473  ++__out_true;
3474  }
3475  else
3476  {
3477  *__out_false = *__first;
3478  ++__out_false;
3479  }
3480 
3481  return {std::move(__first),
3482  std::move(__out_true), std::move(__out_false)};
3483  }
3484 
3485  template<input_range _Range, weakly_incrementable _Out1,
3486  weakly_incrementable _Out2,
3487  typename _Proj = identity,
3488  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
3489  _Pred>
3490  requires indirectly_copyable<iterator_t<_Range>, _Out1>
3491  && indirectly_copyable<iterator_t<_Range>, _Out2>
3492  constexpr partition_copy_result<borrowed_iterator_t<_Range>, _Out1, _Out2>
3493  operator()(_Range&& __r, _Out1 __out_true, _Out2 __out_false,
3494  _Pred __pred, _Proj __proj = {}) const
3495  {
3496  return (*this)(ranges::begin(__r), ranges::end(__r),
3497  std::move(__out_true), std::move(__out_false),
3498  std::move(__pred), std::move(__proj));
3499  }
3500  };
3501 
3502  inline constexpr __partition_copy_fn partition_copy{};
3503 
3504  struct __partition_point_fn
3505  {
3506  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
3507  typename _Proj = identity,
3508  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
3509  [[nodiscard]] constexpr _Iter
3510  operator()(_Iter __first, _Sent __last,
3511  _Pred __pred, _Proj __proj = {}) const
3512  {
3513  auto __len = ranges::distance(__first, __last);
3514 
3515  while (__len > 0)
3516  {
3517  auto __half = __len / 2;
3518  auto __middle = __first;
3519  ranges::advance(__middle, __half);
3520  if (std::__invoke(__pred, std::__invoke(__proj, *__middle)))
3521  {
3522  __first = __middle;
3523  ++__first;
3524  __len = __len - __half - 1;
3525  }
3526  else
3527  __len = __half;
3528  }
3529  return __first;
3530  }
3531 
3532  template<forward_range _Range, typename _Proj = identity,
3533  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
3534  _Pred>
3535  [[nodiscard]] constexpr borrowed_iterator_t<_Range>
3536  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
3537  {
3538  return (*this)(ranges::begin(__r), ranges::end(__r),
3539  std::move(__pred), std::move(__proj));
3540  }
3541  };
3542 
3543  inline constexpr __partition_point_fn partition_point{};
3544 
3545  template<typename _Iter1, typename _Iter2, typename _Out>
3546  using merge_result = in_in_out_result<_Iter1, _Iter2, _Out>;
3547 
3548  struct __merge_fn
3549  {
3550  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
3551  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
3552  weakly_incrementable _Out, typename _Comp = ranges::less,
3553  typename _Proj1 = identity, typename _Proj2 = identity>
3554  requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
3555  constexpr merge_result<_Iter1, _Iter2, _Out>
3556  operator()(_Iter1 __first1, _Sent1 __last1,
3557  _Iter2 __first2, _Sent2 __last2, _Out __result,
3558  _Comp __comp = {},
3559  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
3560  {
3561  while (__first1 != __last1 && __first2 != __last2)
3562  {
3563  if (std::__invoke(__comp,
3564  std::__invoke(__proj2, *__first2),
3565  std::__invoke(__proj1, *__first1)))
3566  {
3567  *__result = *__first2;
3568  ++__first2;
3569  }
3570  else
3571  {
3572  *__result = *__first1;
3573  ++__first1;
3574  }
3575  ++__result;
3576  }
3577  auto __copy1 = ranges::copy(std::move(__first1), std::move(__last1),
3578  std::move(__result));
3579  auto __copy2 = ranges::copy(std::move(__first2), std::move(__last2),
3580  std::move(__copy1.out));
3581  return { std::move(__copy1.in), std::move(__copy2.in),
3582  std::move(__copy2.out) };
3583  }
3584 
3585  template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
3586  typename _Comp = ranges::less,
3587  typename _Proj1 = identity, typename _Proj2 = identity>
3588  requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
3589  _Comp, _Proj1, _Proj2>
3590  constexpr merge_result<borrowed_iterator_t<_Range1>,
3591  borrowed_iterator_t<_Range2>,
3592  _Out>
3593  operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
3594  _Comp __comp = {},
3595  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
3596  {
3597  return (*this)(ranges::begin(__r1), ranges::end(__r1),
3598  ranges::begin(__r2), ranges::end(__r2),
3599  std::move(__result), std::move(__comp),
3600  std::move(__proj1), std::move(__proj2));
3601  }
3602  };
3603 
3604  inline constexpr __merge_fn merge{};
3605 
3606  namespace __detail
3607  {
3608  template<typename _Iter1, typename _Iter2, typename _Out, typename _Comp>
3609  void
3610  __move_merge_adaptive(_Iter1 __first1, _Iter1 __last1,
3611  _Iter2 __first2, _Iter2 __last2,
3612  _Out __result, _Comp __comp)
3613  {
3614  while (__first1 != __last1 && __first2 != __last2)
3615  {
3616  if (__comp(*__first2, *__first1))
3617  {
3618  *__result = ranges::iter_move(__first2);
3619  ++__first2;
3620  }
3621  else
3622  {
3623  *__result = ranges::iter_move(__first1);
3624  ++__first1;
3625  }
3626  ++__result;
3627  }
3628  if (__first1 != __last1)
3629  ranges::move(__first1, __last1, __result);
3630  }
3631 
3632  template<typename _Iter1, typename _Iter2, typename _Iter3, typename _Comp>
3633  void
3634  __move_merge_adaptive_backward(_Iter1 __first1, _Iter1 __last1,
3635  _Iter2 __first2, _Iter2 __last2,
3636  _Iter3 __result, _Comp __comp)
3637  {
3638  if (__first1 == __last1)
3639  {
3640  ranges::move_backward(__first2, __last2, __result);
3641  return;
3642  }
3643  else if (__first2 == __last2)
3644  return;
3645 
3646  --__last1;
3647  --__last2;
3648  while (true)
3649  {
3650  if (__comp(*__last2, *__last1))
3651  {
3652  *--__result = ranges::iter_move(__last1);
3653  if (__first1 == __last1)
3654  {
3655  ranges::move_backward(__first2, ++__last2, __result);
3656  return;
3657  }
3658  --__last1;
3659  }
3660  else
3661  {
3662  *--__result = ranges::iter_move(__last2);
3663  if (__first2 == __last2)
3664  return;
3665  --__last2;
3666  }
3667  }
3668  }
3669 
3670  template<typename _Iter1, typename _Iter2>
3671  _Iter1
3672  __rotate_adaptive(_Iter1 __first, _Iter1 __middle, _Iter1 __last,
3673  iter_difference_t<_Iter1> __len1,
3674  iter_difference_t<_Iter1> __len2,
3675  _Iter2 __buffer,
3676  iter_difference_t<_Iter1> __buffer_size)
3677  {
3678  _Iter2 __buffer_end;
3679  if (__len1 > __len2 && __len2 <= __buffer_size)
3680  {
3681  if (__len2)
3682  {
3683  __buffer_end = ranges::move(__middle, __last, __buffer).out;
3684  ranges::move_backward(__first, __middle, __last);
3685  return ranges::move(__buffer, __buffer_end, __first).out;
3686  }
3687  else
3688  return __first;
3689  }
3690  else if (__len1 <= __buffer_size)
3691  {
3692  if (__len1)
3693  {
3694  __buffer_end = ranges::move(__first, __middle, __buffer).out;
3695  ranges::move(__middle, __last, __first);
3696  return ranges::move_backward(__buffer, __buffer_end, __last).out;
3697  }
3698  else
3699  return __last;
3700  }
3701  else
3702  return ranges::rotate(__first, __middle, __last).begin();
3703  }
3704 
3705  template<typename _Iter, typename _Pointer, typename _Comp>
3706  void
3707  __merge_adaptive(_Iter __first, _Iter __middle, _Iter __last,
3708  iter_difference_t<_Iter> __len1,
3709  iter_difference_t<_Iter> __len2,
3710  _Pointer __buffer, _Comp __comp)
3711  {
3712  if (__len1 <= __len2)
3713  {
3714  _Pointer __buffer_end = ranges::move(__first, __middle, __buffer).out;
3715  __detail::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
3716  __first, __comp);
3717  }
3718  else
3719  {
3720  _Pointer __buffer_end = ranges::move(__middle, __last, __buffer).out;
3721  __detail::__move_merge_adaptive_backward(__first, __middle, __buffer,
3722  __buffer_end, __last, __comp);
3723  }
3724  }
3725 
3726  template<typename _Iter, typename _Distance, typename _Pointer, typename _Comp>
3727  void
3728  __merge_adaptive_resize(_Iter __first, _Iter __middle, _Iter __last,
3729  _Distance __len1, _Distance __len2,
3730  _Pointer __buffer, _Distance __buffer_size,
3731  _Comp __comp)
3732  {
3733  if (__len1 <= __buffer_size || __len2 <= __buffer_size)
3734  __detail::__merge_adaptive(__first, __middle, __last,
3735  __len1, __len2, __buffer, __comp);
3736  else
3737  {
3738  _Iter __first_cut = __first;
3739  _Iter __second_cut = __middle;
3740  _Distance __len11 = 0;
3741  _Distance __len22 = 0;
3742  if (__len1 > __len2)
3743  {
3744  __len11 = __len1 / 2;
3745  ranges::advance(__first_cut, __len11);
3746  __second_cut = ranges::lower_bound(__middle, __last, *__first_cut,
3747  __comp);
3748  __len22 = ranges::distance(__middle, __second_cut);
3749  }
3750  else
3751  {
3752  __len22 = __len2 / 2;
3753  ranges::advance(__second_cut, __len22);
3754  __first_cut = ranges::upper_bound(__first, __middle, *__second_cut,
3755  __comp);
3756  __len11 = ranges::distance(__first, __first_cut);
3757  }
3758 
3759  _Iter __new_middle
3760  = __detail::__rotate_adaptive(__first_cut, __middle, __second_cut,
3761  _Distance(__len1 - __len11), __len22,
3762  __buffer, __buffer_size);
3763  __detail::__merge_adaptive_resize(__first, __first_cut, __new_middle,
3764  __len11, __len22,
3765  __buffer, __buffer_size, __comp);
3766  __detail::__merge_adaptive_resize(__new_middle, __second_cut, __last,
3767  _Distance(__len1 - __len11),
3768  _Distance(__len2 - __len22),
3769  __buffer, __buffer_size, __comp);
3770  }
3771  }
3772 
3773  template<typename _Iter, typename _Distance, typename _Comp>
3774  constexpr void
3775  __merge_without_buffer(_Iter __first, _Iter __middle, _Iter __last,
3776  _Distance __len1, _Distance __len2, _Comp __comp)
3777  {
3778  if (__len1 == 0 || __len2 == 0)
3779  return;
3780 
3781  if (__len1 + __len2 == 2)
3782  {
3783  if (__comp(*__middle, *__first))
3784  ranges::iter_swap(__first, __middle);
3785  return;
3786  }
3787 
3788  _Iter __first_cut = __first;
3789  _Iter __second_cut = __middle;
3790  _Distance __len11 = 0;
3791  _Distance __len22 = 0;
3792  if (__len1 > __len2)
3793  {
3794  __len11 = __len1 / 2;
3795  ranges::advance(__first_cut, __len11);
3796  __second_cut = ranges::lower_bound(__middle, __last, *__first_cut, __comp);
3797  __len22 = ranges::distance(__middle, __second_cut);
3798  }
3799  else
3800  {
3801  __len22 = __len2 / 2;
3802  ranges::advance(__second_cut, __len22);
3803  __first_cut = ranges::upper_bound(__first, __middle, *__second_cut, __comp);
3804  __len11 = ranges::distance(__first, __first_cut);
3805  }
3806 
3807  _Iter __new_middle = ranges::rotate(__first_cut, __middle, __second_cut).begin();
3808  __detail::__merge_without_buffer(__first, __first_cut, __new_middle,
3809  __len11, __len22, __comp);
3810  __detail::__merge_without_buffer(__new_middle, __second_cut, __last,
3811  __len1 - __len11, __len2 - __len22, __comp);
3812  }
3813  } // namespace __detail
3814 
3815  struct __inplace_merge_fn
3816  {
3817  template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
3818  typename _Comp = ranges::less,
3819  typename _Proj = identity>
3820  requires sortable<_Iter, _Comp, _Proj>
3821  _GLIBCXX26_CONSTEXPR
3822  _Iter
3823  operator()(_Iter __first, _Iter __middle, _Sent __last,
3824  _Comp __comp = {}, _Proj __proj = {}) const
3825  {
3826  if constexpr (!same_as<_Iter, _Sent>)
3827  return (*this)(__first, __middle, ranges::next(__middle, __last),
3828  std::move(__comp), std::move(__proj));
3829  else
3830  {
3831  using _DistanceType = iter_difference_t<_Iter>;
3832 
3833  if (__first == __middle || __middle == __last)
3834  return __last;
3835 
3836  const _DistanceType __len1 = ranges::distance(__first, __middle);
3837  const _DistanceType __len2 = ranges::distance(__middle, __last);
3838 
3839  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
3840 
3841 #if _GLIBCXX_HOSTED
3842 # if __glibcxx_constexpr_algorithms >= 202306L // >= C++26
3843  if consteval {
3844  __detail::__merge_without_buffer(__first, __middle, __last,
3845  __len1, __len2, __comp_proj);
3846  return __last;
3847  }
3848 # endif
3849  using _TmpBuf = _Temporary_buffer<_Iter, iter_value_t<_Iter>>;
3850  // __merge_adaptive will use a buffer for the smaller of
3851  // [first,middle) and [middle,last).
3852  _TmpBuf __buf(__first, ptrdiff_t(ranges::min(__len1, __len2)));
3853 
3854  if (__buf.size() == __buf._M_requested_size()) [[likely]]
3855  __detail::__merge_adaptive
3856  (__first, __middle, __last, __len1, __len2, __buf.begin(), __comp_proj);
3857  else if (__buf.begin() == 0) [[unlikely]]
3858  __detail::__merge_without_buffer
3859  (__first, __middle, __last, __len1, __len2, __comp_proj);
3860  else
3861  __detail::__merge_adaptive_resize
3862  (__first, __middle, __last, __len1, __len2, __buf.begin(),
3863  _DistanceType(__buf.size()), __comp_proj);
3864 #else
3865  __detail::__merge_without_buffer
3866  (__first, __middle, __last, __len1, __len2, __comp_proj);
3867 #endif
3868  return __last;
3869  }
3870  }
3871 
3872  template<bidirectional_range _Range,
3873  typename _Comp = ranges::less, typename _Proj = identity>
3874  requires sortable<iterator_t<_Range>, _Comp, _Proj>
3875  _GLIBCXX26_CONSTEXPR
3876  borrowed_iterator_t<_Range>
3877  operator()(_Range&& __r, iterator_t<_Range> __middle,
3878  _Comp __comp = {}, _Proj __proj = {}) const
3879  {
3880  return (*this)(ranges::begin(__r), std::move(__middle),
3881  ranges::end(__r),
3882  std::move(__comp), std::move(__proj));
3883  }
3884  };
3885 
3886  inline constexpr __inplace_merge_fn inplace_merge{};
3887 
3888  struct __includes_fn
3889  {
3890  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
3891  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
3892  typename _Proj1 = identity, typename _Proj2 = identity,
3893  indirect_strict_weak_order<projected<_Iter1, _Proj1>,
3894  projected<_Iter2, _Proj2>>
3895  _Comp = ranges::less>
3896  [[nodiscard]] constexpr bool
3897  operator()(_Iter1 __first1, _Sent1 __last1,
3898  _Iter2 __first2, _Sent2 __last2,
3899  _Comp __comp = {},
3900  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
3901  {
3902  while (__first1 != __last1 && __first2 != __last2)
3903  if (std::__invoke(__comp,
3904  std::__invoke(__proj2, *__first2),
3905  std::__invoke(__proj1, *__first1)))
3906  return false;
3907  else if (std::__invoke(__comp,
3908  std::__invoke(__proj1, *__first1),
3909  std::__invoke(__proj2, *__first2)))
3910  ++__first1;
3911  else
3912  {
3913  ++__first1;
3914  ++__first2;
3915  }
3916 
3917  return __first2 == __last2;
3918  }
3919 
3920  template<input_range _Range1, input_range _Range2,
3921  typename _Proj1 = identity, typename _Proj2 = identity,
3922  indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
3923  projected<iterator_t<_Range2>, _Proj2>>
3924  _Comp = ranges::less>
3925  [[nodiscard]] constexpr bool
3926  operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {},
3927  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
3928  {
3929  return (*this)(ranges::begin(__r1), ranges::end(__r1),
3930  ranges::begin(__r2), ranges::end(__r2),
3931  std::move(__comp),
3932  std::move(__proj1), std::move(__proj2));
3933  }
3934  };
3935 
3936  inline constexpr __includes_fn includes{};
3937 
3938  template<typename _Iter1, typename _Iter2, typename _Out>
3939  using set_union_result = in_in_out_result<_Iter1, _Iter2, _Out>;
3940 
3941  struct __set_union_fn
3942  {
3943  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
3944  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
3945  weakly_incrementable _Out, typename _Comp = ranges::less,
3946  typename _Proj1 = identity, typename _Proj2 = identity>
3947  requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
3948  constexpr set_union_result<_Iter1, _Iter2, _Out>
3949  operator()(_Iter1 __first1, _Sent1 __last1,
3950  _Iter2 __first2, _Sent2 __last2,
3951  _Out __result, _Comp __comp = {},
3952  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
3953  {
3954  while (__first1 != __last1 && __first2 != __last2)
3955  {
3956  if (std::__invoke(__comp,
3957  std::__invoke(__proj1, *__first1),
3958  std::__invoke(__proj2, *__first2)))
3959  {
3960  *__result = *__first1;
3961  ++__first1;
3962  }
3963  else if (std::__invoke(__comp,
3964  std::__invoke(__proj2, *__first2),
3965  std::__invoke(__proj1, *__first1)))
3966  {
3967  *__result = *__first2;
3968  ++__first2;
3969  }
3970  else
3971  {
3972  *__result = *__first1;
3973  ++__first1;
3974  ++__first2;
3975  }
3976  ++__result;
3977  }
3978  auto __copy1 = ranges::copy(std::move(__first1), std::move(__last1),
3979  std::move(__result));
3980  auto __copy2 = ranges::copy(std::move(__first2), std::move(__last2),
3981  std::move(__copy1.out));
3982  return {std::move(__copy1.in), std::move(__copy2.in),
3983  std::move(__copy2.out)};
3984  }
3985 
3986  template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
3987  typename _Comp = ranges::less,
3988  typename _Proj1 = identity, typename _Proj2 = identity>
3989  requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
3990  _Comp, _Proj1, _Proj2>
3991  constexpr set_union_result<borrowed_iterator_t<_Range1>,
3992  borrowed_iterator_t<_Range2>, _Out>
3993  operator()(_Range1&& __r1, _Range2&& __r2,
3994  _Out __result, _Comp __comp = {},
3995  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
3996  {
3997  return (*this)(ranges::begin(__r1), ranges::end(__r1),
3998  ranges::begin(__r2), ranges::end(__r2),
3999  std::move(__result), std::move(__comp),
4000  std::move(__proj1), std::move(__proj2));
4001  }
4002  };
4003 
4004  inline constexpr __set_union_fn set_union{};
4005 
4006  template<typename _Iter1, typename _Iter2, typename _Out>
4007  using set_intersection_result = in_in_out_result<_Iter1, _Iter2, _Out>;
4008 
4009  struct __set_intersection_fn
4010  {
4011  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
4012  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
4013  weakly_incrementable _Out, typename _Comp = ranges::less,
4014  typename _Proj1 = identity, typename _Proj2 = identity>
4015  requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
4016  constexpr set_intersection_result<_Iter1, _Iter2, _Out>
4017  operator()(_Iter1 __first1, _Sent1 __last1,
4018  _Iter2 __first2, _Sent2 __last2, _Out __result,
4019  _Comp __comp = {},
4020  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4021  {
4022  while (__first1 != __last1 && __first2 != __last2)
4023  if (std::__invoke(__comp,
4024  std::__invoke(__proj1, *__first1),
4025  std::__invoke(__proj2, *__first2)))
4026  ++__first1;
4027  else if (std::__invoke(__comp,
4028  std::__invoke(__proj2, *__first2),
4029  std::__invoke(__proj1, *__first1)))
4030  ++__first2;
4031  else
4032  {
4033  *__result = *__first1;
4034  ++__first1;
4035  ++__first2;
4036  ++__result;
4037  }
4038  // TODO: Eliminating these variables triggers an ICE.
4039  auto __last1i = ranges::next(std::move(__first1), std::move(__last1));
4040  auto __last2i = ranges::next(std::move(__first2), std::move(__last2));
4041  return {std::move(__last1i), std::move(__last2i), std::move(__result)};
4042  }
4043 
4044  template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
4045  typename _Comp = ranges::less,
4046  typename _Proj1 = identity, typename _Proj2 = identity>
4047  requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
4048  _Comp, _Proj1, _Proj2>
4049  constexpr set_intersection_result<borrowed_iterator_t<_Range1>,
4050  borrowed_iterator_t<_Range2>, _Out>
4051  operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
4052  _Comp __comp = {},
4053  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4054  {
4055  return (*this)(ranges::begin(__r1), ranges::end(__r1),
4056  ranges::begin(__r2), ranges::end(__r2),
4057  std::move(__result), std::move(__comp),
4058  std::move(__proj1), std::move(__proj2));
4059  }
4060  };
4061 
4062  inline constexpr __set_intersection_fn set_intersection{};
4063 
4064  template<typename _Iter, typename _Out>
4065  using set_difference_result = in_out_result<_Iter, _Out>;
4066 
4067  struct __set_difference_fn
4068  {
4069  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
4070  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
4071  weakly_incrementable _Out, typename _Comp = ranges::less,
4072  typename _Proj1 = identity, typename _Proj2 = identity>
4073  requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
4074  constexpr set_difference_result<_Iter1, _Out>
4075  operator()(_Iter1 __first1, _Sent1 __last1,
4076  _Iter2 __first2, _Sent2 __last2, _Out __result,
4077  _Comp __comp = {},
4078  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4079  {
4080  while (__first1 != __last1 && __first2 != __last2)
4081  if (std::__invoke(__comp,
4082  std::__invoke(__proj1, *__first1),
4083  std::__invoke(__proj2, *__first2)))
4084  {
4085  *__result = *__first1;
4086  ++__first1;
4087  ++__result;
4088  }
4089  else if (std::__invoke(__comp,
4090  std::__invoke(__proj2, *__first2),
4091  std::__invoke(__proj1, *__first1)))
4092  ++__first2;
4093  else
4094  {
4095  ++__first1;
4096  ++__first2;
4097  }
4098  return ranges::copy(std::move(__first1), std::move(__last1),
4099  std::move(__result));
4100  }
4101 
4102  template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
4103  typename _Comp = ranges::less,
4104  typename _Proj1 = identity, typename _Proj2 = identity>
4105  requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
4106  _Comp, _Proj1, _Proj2>
4107  constexpr set_difference_result<borrowed_iterator_t<_Range1>, _Out>
4108  operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
4109  _Comp __comp = {},
4110  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4111  {
4112  return (*this)(ranges::begin(__r1), ranges::end(__r1),
4113  ranges::begin(__r2), ranges::end(__r2),
4114  std::move(__result), std::move(__comp),
4115  std::move(__proj1), std::move(__proj2));
4116  }
4117  };
4118 
4119  inline constexpr __set_difference_fn set_difference{};
4120 
4121  template<typename _Iter1, typename _Iter2, typename _Out>
4122  using set_symmetric_difference_result
4123  = in_in_out_result<_Iter1, _Iter2, _Out>;
4124 
4125  struct __set_symmetric_difference_fn
4126  {
4127  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
4128  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
4129  weakly_incrementable _Out, typename _Comp = ranges::less,
4130  typename _Proj1 = identity, typename _Proj2 = identity>
4131  requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2>
4132  constexpr set_symmetric_difference_result<_Iter1, _Iter2, _Out>
4133  operator()(_Iter1 __first1, _Sent1 __last1,
4134  _Iter2 __first2, _Sent2 __last2,
4135  _Out __result, _Comp __comp = {},
4136  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4137  {
4138  while (__first1 != __last1 && __first2 != __last2)
4139  if (std::__invoke(__comp,
4140  std::__invoke(__proj1, *__first1),
4141  std::__invoke(__proj2, *__first2)))
4142  {
4143  *__result = *__first1;
4144  ++__first1;
4145  ++__result;
4146  }
4147  else if (std::__invoke(__comp,
4148  std::__invoke(__proj2, *__first2),
4149  std::__invoke(__proj1, *__first1)))
4150  {
4151  *__result = *__first2;
4152  ++__first2;
4153  ++__result;
4154  }
4155  else
4156  {
4157  ++__first1;
4158  ++__first2;
4159  }
4160  auto __copy1 = ranges::copy(std::move(__first1), std::move(__last1),
4161  std::move(__result));
4162  auto __copy2 = ranges::copy(std::move(__first2), std::move(__last2),
4163  std::move(__copy1.out));
4164  return {std::move(__copy1.in), std::move(__copy2.in),
4165  std::move(__copy2.out)};
4166  }
4167 
4168  template<input_range _Range1, input_range _Range2, weakly_incrementable _Out,
4169  typename _Comp = ranges::less,
4170  typename _Proj1 = identity, typename _Proj2 = identity>
4171  requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
4172  _Comp, _Proj1, _Proj2>
4173  constexpr set_symmetric_difference_result<borrowed_iterator_t<_Range1>,
4174  borrowed_iterator_t<_Range2>,
4175  _Out>
4176  operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
4177  _Comp __comp = {},
4178  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4179  {
4180  return (*this)(ranges::begin(__r1), ranges::end(__r1),
4181  ranges::begin(__r2), ranges::end(__r2),
4182  std::move(__result), std::move(__comp),
4183  std::move(__proj1), std::move(__proj2));
4184  }
4185  };
4186 
4187  inline constexpr __set_symmetric_difference_fn set_symmetric_difference{};
4188 
4189  // min is defined in <bits/ranges_util.h>.
4190 
4191  struct __max_fn
4192  {
4193  template<typename _Tp, typename _Proj = identity,
4194  indirect_strict_weak_order<projected<const _Tp*, _Proj>>
4195  _Comp = ranges::less>
4196  [[nodiscard]] constexpr const _Tp&
4197  operator()(const _Tp& __a, const _Tp& __b,
4198  _Comp __comp = {}, _Proj __proj = {}) const
4199  {
4200  if (std::__invoke(__comp,
4201  std::__invoke(__proj, __a),
4202  std::__invoke(__proj, __b)))
4203  return __b;
4204  else
4205  return __a;
4206  }
4207 
4208  template<input_range _Range, typename _Proj = identity,
4209  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
4210  _Comp = ranges::less>
4211  requires indirectly_copyable_storable<iterator_t<_Range>,
4212  range_value_t<_Range>*>
4213  [[nodiscard]] constexpr range_value_t<_Range>
4214  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
4215  {
4216  auto __first = ranges::begin(__r);
4217  auto __last = ranges::end(__r);
4218  __glibcxx_assert(__first != __last);
4219  range_value_t<_Range> __result(*__first);
4220  while (++__first != __last)
4221  {
4222  auto&& __tmp = *__first;
4223  if (std::__invoke(__comp,
4224  std::__invoke(__proj, __result),
4225  std::__invoke(__proj, __tmp)))
4226  __result = std::forward<decltype(__tmp)>(__tmp);
4227  }
4228  return __result;
4229  }
4230 
4231  template<copyable _Tp, typename _Proj = identity,
4232  indirect_strict_weak_order<projected<const _Tp*, _Proj>>
4233  _Comp = ranges::less>
4234  [[nodiscard]] constexpr _Tp
4235  operator()(initializer_list<_Tp> __r,
4236  _Comp __comp = {}, _Proj __proj = {}) const
4237  {
4238  return (*this)(ranges::subrange(__r),
4239  std::move(__comp), std::move(__proj));
4240  }
4241  };
4242 
4243  inline constexpr __max_fn max{};
4244 
4245  struct __clamp_fn
4246  {
4247  template<typename _Tp, typename _Proj = identity,
4248  indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp
4249  = ranges::less>
4250  [[nodiscard]] constexpr const _Tp&
4251  operator()(const _Tp& __val, const _Tp& __lo, const _Tp& __hi,
4252  _Comp __comp = {}, _Proj __proj = {}) const
4253  {
4254  __glibcxx_assert(!(std::__invoke(__comp,
4255  std::__invoke(__proj, __hi),
4256  std::__invoke(__proj, __lo))));
4257  auto&& __proj_val = std::__invoke(__proj, __val);
4258  if (std::__invoke(__comp,
4259  std::forward<decltype(__proj_val)>(__proj_val),
4260  std::__invoke(__proj, __lo)))
4261  return __lo;
4262  else if (std::__invoke(__comp,
4263  std::__invoke(__proj, __hi),
4264  std::forward<decltype(__proj_val)>(__proj_val)))
4265  return __hi;
4266  else
4267  return __val;
4268  }
4269  };
4270 
4271  inline constexpr __clamp_fn clamp{};
4272 
4273  template<typename _Tp>
4274  struct min_max_result
4275  {
4276  [[no_unique_address]] _Tp min;
4277  [[no_unique_address]] _Tp max;
4278 
4279  template<typename _Tp2>
4280  requires convertible_to<const _Tp&, _Tp2>
4281  constexpr
4282  operator min_max_result<_Tp2>() const &
4283  { return {min, max}; }
4284 
4285  template<typename _Tp2>
4286  requires convertible_to<_Tp, _Tp2>
4287  constexpr
4288  operator min_max_result<_Tp2>() &&
4289  { return {std::move(min), std::move(max)}; }
4290  };
4291 
4292  template<typename _Tp>
4293  using minmax_result = min_max_result<_Tp>;
4294 
4295  struct __minmax_fn
4296  {
4297  template<typename _Tp, typename _Proj = identity,
4298  indirect_strict_weak_order<projected<const _Tp*, _Proj>>
4299  _Comp = ranges::less>
4300  [[nodiscard]] constexpr minmax_result<const _Tp&>
4301  operator()(const _Tp& __a, const _Tp& __b,
4302  _Comp __comp = {}, _Proj __proj = {}) const
4303  {
4304  if (std::__invoke(__comp,
4305  std::__invoke(__proj, __b),
4306  std::__invoke(__proj, __a)))
4307  return {__b, __a};
4308  else
4309  return {__a, __b};
4310  }
4311 
4312  template<input_range _Range, typename _Proj = identity,
4313  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
4314  _Comp = ranges::less>
4315  requires indirectly_copyable_storable<iterator_t<_Range>, range_value_t<_Range>*>
4316  [[nodiscard]] constexpr minmax_result<range_value_t<_Range>>
4317  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
4318  {
4319  auto __first = ranges::begin(__r);
4320  auto __last = ranges::end(__r);
4321  __glibcxx_assert(__first != __last);
4322  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
4323  minmax_result<range_value_t<_Range>> __result = {*__first, __result.min};
4324  if (++__first == __last)
4325  return __result;
4326  else
4327  {
4328  // At this point __result.min == __result.max, so a single
4329  // comparison with the next element suffices.
4330  auto&& __val = *__first;
4331  if (__comp_proj(__val, __result.min))
4332  __result.min = std::forward<decltype(__val)>(__val);
4333  else
4334  __result.max = std::forward<decltype(__val)>(__val);
4335  }
4336  while (++__first != __last)
4337  {
4338  // Now process two elements at a time so that we perform at most
4339  // 1 + 3*(N-2)/2 comparisons in total (each of the (N-2)/2
4340  // iterations of this loop performs three comparisons).
4341  range_value_t<_Range> __val1 = *__first;
4342  if (++__first == __last)
4343  {
4344  // N is odd; in this final iteration, we perform at most two
4345  // comparisons, for a total of 1 + 3*(N-3)/2 + 2 comparisons,
4346  // which is not more than 3*N/2, as required.
4347  if (__comp_proj(__val1, __result.min))
4348  __result.min = std::move(__val1);
4349  else if (!__comp_proj(__val1, __result.max))
4350  __result.max = std::move(__val1);
4351  break;
4352  }
4353  auto&& __val2 = *__first;
4354  if (!__comp_proj(__val2, __val1))
4355  {
4356  if (__comp_proj(__val1, __result.min))
4357  __result.min = std::move(__val1);
4358  if (!__comp_proj(__val2, __result.max))
4359  __result.max = std::forward<decltype(__val2)>(__val2);
4360  }
4361  else
4362  {
4363  if (__comp_proj(__val2, __result.min))
4364  __result.min = std::forward<decltype(__val2)>(__val2);
4365  if (!__comp_proj(__val1, __result.max))
4366  __result.max = std::move(__val1);
4367  }
4368  }
4369  return __result;
4370  }
4371 
4372  template<copyable _Tp, typename _Proj = identity,
4373  indirect_strict_weak_order<projected<const _Tp*, _Proj>>
4374  _Comp = ranges::less>
4375  [[nodiscard]] constexpr minmax_result<_Tp>
4376  operator()(initializer_list<_Tp> __r,
4377  _Comp __comp = {}, _Proj __proj = {}) const
4378  {
4379  return (*this)(ranges::subrange(__r),
4380  std::move(__comp), std::move(__proj));
4381  }
4382  };
4383 
4384  inline constexpr __minmax_fn minmax{};
4385 
4386  struct __min_element_fn
4387  {
4388  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
4389  typename _Proj = identity,
4390  indirect_strict_weak_order<projected<_Iter, _Proj>>
4391  _Comp = ranges::less>
4392  [[nodiscard]] constexpr _Iter
4393  operator()(_Iter __first, _Sent __last,
4394  _Comp __comp = {}, _Proj __proj = {}) const
4395  {
4396  if (__first == __last)
4397  return __first;
4398 
4399  auto __i = __first;
4400  while (++__i != __last)
4401  {
4402  if (std::__invoke(__comp,
4403  std::__invoke(__proj, *__i),
4404  std::__invoke(__proj, *__first)))
4405  __first = __i;
4406  }
4407  return __first;
4408  }
4409 
4410  template<forward_range _Range, typename _Proj = identity,
4411  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
4412  _Comp = ranges::less>
4413  [[nodiscard]] constexpr borrowed_iterator_t<_Range>
4414  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
4415  {
4416  return (*this)(ranges::begin(__r), ranges::end(__r),
4417  std::move(__comp), std::move(__proj));
4418  }
4419  };
4420 
4421  inline constexpr __min_element_fn min_element{};
4422 
4423  struct __max_element_fn
4424  {
4425  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
4426  typename _Proj = identity,
4427  indirect_strict_weak_order<projected<_Iter, _Proj>>
4428  _Comp = ranges::less>
4429  [[nodiscard]] constexpr _Iter
4430  operator()(_Iter __first, _Sent __last,
4431  _Comp __comp = {}, _Proj __proj = {}) const
4432  {
4433  if (__first == __last)
4434  return __first;
4435 
4436  auto __i = __first;
4437  while (++__i != __last)
4438  {
4439  if (std::__invoke(__comp,
4440  std::__invoke(__proj, *__first),
4441  std::__invoke(__proj, *__i)))
4442  __first = __i;
4443  }
4444  return __first;
4445  }
4446 
4447  template<forward_range _Range, typename _Proj = identity,
4448  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
4449  _Comp = ranges::less>
4450  [[nodiscard]] constexpr borrowed_iterator_t<_Range>
4451  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
4452  {
4453  return (*this)(ranges::begin(__r), ranges::end(__r),
4454  std::move(__comp), std::move(__proj));
4455  }
4456  };
4457 
4458  inline constexpr __max_element_fn max_element{};
4459 
4460  template<typename _Iter>
4461  using minmax_element_result = min_max_result<_Iter>;
4462 
4463  struct __minmax_element_fn
4464  {
4465  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
4466  typename _Proj = identity,
4467  indirect_strict_weak_order<projected<_Iter, _Proj>>
4468  _Comp = ranges::less>
4469  [[nodiscard]] constexpr minmax_element_result<_Iter>
4470  operator()(_Iter __first, _Sent __last,
4471  _Comp __comp = {}, _Proj __proj = {}) const
4472  {
4473  auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
4474  minmax_element_result<_Iter> __result = {__first, __first};
4475  if (__first == __last || ++__first == __last)
4476  return __result;
4477  else
4478  {
4479  // At this point __result.min == __result.max, so a single
4480  // comparison with the next element suffices.
4481  if (__comp_proj(*__first, *__result.min))
4482  __result.min = __first;
4483  else
4484  __result.max = __first;
4485  }
4486  while (++__first != __last)
4487  {
4488  // Now process two elements at a time so that we perform at most
4489  // 1 + 3*(N-2)/2 comparisons in total (each of the (N-2)/2
4490  // iterations of this loop performs three comparisons).
4491  auto __prev = __first;
4492  if (++__first == __last)
4493  {
4494  // N is odd; in this final iteration, we perform at most two
4495  // comparisons, for a total of 1 + 3*(N-3)/2 + 2 comparisons,
4496  // which is not more than 3*N/2, as required.
4497  if (__comp_proj(*__prev, *__result.min))
4498  __result.min = __prev;
4499  else if (!__comp_proj(*__prev, *__result.max))
4500  __result.max = __prev;
4501  break;
4502  }
4503  if (!__comp_proj(*__first, *__prev))
4504  {
4505  if (__comp_proj(*__prev, *__result.min))
4506  __result.min = __prev;
4507  if (!__comp_proj(*__first, *__result.max))
4508  __result.max = __first;
4509  }
4510  else
4511  {
4512  if (__comp_proj(*__first, *__result.min))
4513  __result.min = __first;
4514  if (!__comp_proj(*__prev, *__result.max))
4515  __result.max = __prev;
4516  }
4517  }
4518  return __result;
4519  }
4520 
4521  template<forward_range _Range, typename _Proj = identity,
4522  indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
4523  _Comp = ranges::less>
4524  [[nodiscard]] constexpr minmax_element_result<borrowed_iterator_t<_Range>>
4525  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
4526  {
4527  return (*this)(ranges::begin(__r), ranges::end(__r),
4528  std::move(__comp), std::move(__proj));
4529  }
4530  };
4531 
4532  inline constexpr __minmax_element_fn minmax_element{};
4533 
4534  struct __lexicographical_compare_fn
4535  {
4536  template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
4537  input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
4538  typename _Proj1 = identity, typename _Proj2 = identity,
4539  indirect_strict_weak_order<projected<_Iter1, _Proj1>,
4540  projected<_Iter2, _Proj2>>
4541  _Comp = ranges::less>
4542  [[nodiscard]] constexpr bool
4543  operator()(_Iter1 __first1, _Sent1 __last1,
4544  _Iter2 __first2, _Sent2 __last2,
4545  _Comp __comp = {},
4546  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4547  {
4548  if constexpr (__detail::__is_normal_iterator<_Iter1>
4549  && same_as<_Iter1, _Sent1>)
4550  return (*this)(__first1.base(), __last1.base(),
4551  std::move(__first2), std::move(__last2),
4552  std::move(__comp),
4553  std::move(__proj1), std::move(__proj2));
4554  else if constexpr (__detail::__is_normal_iterator<_Iter2>
4555  && same_as<_Iter2, _Sent2>)
4556  return (*this)(std::move(__first1), std::move(__last1),
4557  __first2.base(), __last2.base(),
4558  std::move(__comp),
4559  std::move(__proj1), std::move(__proj2));
4560  else
4561  {
4562  constexpr bool __sized_iters
4563  = (sized_sentinel_for<_Sent1, _Iter1>
4564  && sized_sentinel_for<_Sent2, _Iter2>);
4565  if constexpr (__sized_iters)
4566  {
4567  using _ValueType1 = iter_value_t<_Iter1>;
4568  using _ValueType2 = iter_value_t<_Iter2>;
4569  // This condition is consistent with the one in
4570  // __lexicographical_compare_aux in <bits/stl_algobase.h>.
4571  constexpr bool __use_memcmp
4572  = (__is_memcmp_ordered_with<_ValueType1, _ValueType2>::__value
4573  && __ptr_to_nonvolatile<_Iter1>
4574  && __ptr_to_nonvolatile<_Iter2>
4575  && (is_same_v<_Comp, ranges::less>
4576  || is_same_v<_Comp, ranges::greater>)
4577  && is_same_v<_Proj1, identity>
4578  && is_same_v<_Proj2, identity>);
4579  if constexpr (__use_memcmp)
4580  {
4581  const auto __d1 = __last1 - __first1;
4582  const auto __d2 = __last2 - __first2;
4583 
4584  if (const auto __len = std::min(__d1, __d2))
4585  {
4586  const auto __c
4587  = std::__memcmp(__first1, __first2, __len);
4588  if constexpr (is_same_v<_Comp, ranges::less>)
4589  {
4590  if (__c < 0)
4591  return true;
4592  if (__c > 0)
4593  return false;
4594  }
4595  else if constexpr (is_same_v<_Comp, ranges::greater>)
4596  {
4597  if (__c > 0)
4598  return true;
4599  if (__c < 0)
4600  return false;
4601  }
4602  }
4603  return __d1 < __d2;
4604  }
4605  }
4606 
4607  for (; __first1 != __last1 && __first2 != __last2;
4608  ++__first1, (void) ++__first2)
4609  {
4610  if (std::__invoke(__comp,
4611  std::__invoke(__proj1, *__first1),
4612  std::__invoke(__proj2, *__first2)))
4613  return true;
4614  if (std::__invoke(__comp,
4615  std::__invoke(__proj2, *__first2),
4616  std::__invoke(__proj1, *__first1)))
4617  return false;
4618  }
4619  return __first1 == __last1 && __first2 != __last2;
4620  }
4621  }
4622 
4623  template<input_range _Range1, input_range _Range2,
4624  typename _Proj1 = identity, typename _Proj2 = identity,
4625  indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
4626  projected<iterator_t<_Range2>, _Proj2>>
4627  _Comp = ranges::less>
4628  [[nodiscard]] constexpr bool
4629  operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {},
4630  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4631  {
4632  return (*this)(ranges::begin(__r1), ranges::end(__r1),
4633  ranges::begin(__r2), ranges::end(__r2),
4634  std::move(__comp),
4635  std::move(__proj1), std::move(__proj2));
4636  }
4637 
4638  private:
4639  template<typename _Iter, typename _Ref = iter_reference_t<_Iter>>
4640  static constexpr bool __ptr_to_nonvolatile
4641  = is_pointer_v<_Iter> && !is_volatile_v<remove_reference_t<_Ref>>;
4642  };
4643 
4644  inline constexpr __lexicographical_compare_fn lexicographical_compare;
4645 
4646  template<typename _Iter>
4647  struct in_found_result
4648  {
4649  [[no_unique_address]] _Iter in;
4650  bool found;
4651 
4652  template<typename _Iter2>
4653  requires convertible_to<const _Iter&, _Iter2>
4654  constexpr
4655  operator in_found_result<_Iter2>() const &
4656  { return {in, found}; }
4657 
4658  template<typename _Iter2>
4659  requires convertible_to<_Iter, _Iter2>
4660  constexpr
4661  operator in_found_result<_Iter2>() &&
4662  { return {std::move(in), found}; }
4663  };
4664 
4665  template<typename _Iter>
4666  using next_permutation_result = in_found_result<_Iter>;
4667 
4668  struct __next_permutation_fn
4669  {
4670  template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
4671  typename _Comp = ranges::less, typename _Proj = identity>
4672  requires sortable<_Iter, _Comp, _Proj>
4673  constexpr next_permutation_result<_Iter>
4674  operator()(_Iter __first, _Sent __last,
4675  _Comp __comp = {}, _Proj __proj = {}) const
4676  {
4677  if (__first == __last)
4678  return {std::move(__first), false};
4679 
4680  auto __i = __first;
4681  ++__i;
4682  if (__i == __last)
4683  return {std::move(__i), false};
4684 
4685  auto __lasti = ranges::next(__first, __last);
4686  __i = __lasti;
4687  --__i;
4688 
4689  for (;;)
4690  {
4691  auto __ii = __i;
4692  --__i;
4693  if (std::__invoke(__comp,
4694  std::__invoke(__proj, *__i),
4695  std::__invoke(__proj, *__ii)))
4696  {
4697  auto __j = __lasti;
4698  while (!(bool)std::__invoke(__comp,
4699  std::__invoke(__proj, *__i),
4700  std::__invoke(__proj, *--__j)))
4701  ;
4702  ranges::iter_swap(__i, __j);
4703  ranges::reverse(__ii, __last);
4704  return {std::move(__lasti), true};
4705  }
4706  if (__i == __first)
4707  {
4708  ranges::reverse(__first, __last);
4709  return {std::move(__lasti), false};
4710  }
4711  }
4712  }
4713 
4714  template<bidirectional_range _Range, typename _Comp = ranges::less,
4715  typename _Proj = identity>
4716  requires sortable<iterator_t<_Range>, _Comp, _Proj>
4717  constexpr next_permutation_result<borrowed_iterator_t<_Range>>
4718  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
4719  {
4720  return (*this)(ranges::begin(__r), ranges::end(__r),
4721  std::move(__comp), std::move(__proj));
4722  }
4723  };
4724 
4725  inline constexpr __next_permutation_fn next_permutation{};
4726 
4727  template<typename _Iter>
4728  using prev_permutation_result = in_found_result<_Iter>;
4729 
4730  struct __prev_permutation_fn
4731  {
4732  template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
4733  typename _Comp = ranges::less, typename _Proj = identity>
4734  requires sortable<_Iter, _Comp, _Proj>
4735  constexpr prev_permutation_result<_Iter>
4736  operator()(_Iter __first, _Sent __last,
4737  _Comp __comp = {}, _Proj __proj = {}) const
4738  {
4739  if (__first == __last)
4740  return {std::move(__first), false};
4741 
4742  auto __i = __first;
4743  ++__i;
4744  if (__i == __last)
4745  return {std::move(__i), false};
4746 
4747  auto __lasti = ranges::next(__first, __last);
4748  __i = __lasti;
4749  --__i;
4750 
4751  for (;;)
4752  {
4753  auto __ii = __i;
4754  --__i;
4755  if (std::__invoke(__comp,
4756  std::__invoke(__proj, *__ii),
4757  std::__invoke(__proj, *__i)))
4758  {
4759  auto __j = __lasti;
4760  while (!(bool)std::__invoke(__comp,
4761  std::__invoke(__proj, *--__j),
4762  std::__invoke(__proj, *__i)))
4763  ;
4764  ranges::iter_swap(__i, __j);
4765  ranges::reverse(__ii, __last);
4766  return {std::move(__lasti), true};
4767  }
4768  if (__i == __first)
4769  {
4770  ranges::reverse(__first, __last);
4771  return {std::move(__lasti), false};
4772  }
4773  }
4774  }
4775 
4776  template<bidirectional_range _Range, typename _Comp = ranges::less,
4777  typename _Proj = identity>
4778  requires sortable<iterator_t<_Range>, _Comp, _Proj>
4779  constexpr prev_permutation_result<borrowed_iterator_t<_Range>>
4780  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
4781  {
4782  return (*this)(ranges::begin(__r), ranges::end(__r),
4783  std::move(__comp), std::move(__proj));
4784  }
4785  };
4786 
4787  inline constexpr __prev_permutation_fn prev_permutation{};
4788 
4789 #if __glibcxx_ranges_contains >= 202207L // C++ >= 23
4790  struct __contains_fn
4791  {
4792  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
4793  typename _Proj = identity,
4794  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
4795  requires indirect_binary_predicate<ranges::equal_to,
4796  projected<_Iter, _Proj>, const _Tp*>
4797  constexpr bool
4798  operator()(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const
4799  { return ranges::find(std::move(__first), __last, __value, std::move(__proj)) != __last; }
4800 
4801  template<input_range _Range,
4802  typename _Proj = identity,
4803  typename _Tp
4804  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj)>
4805  requires indirect_binary_predicate<ranges::equal_to,
4806  projected<iterator_t<_Range>, _Proj>, const _Tp*>
4807  constexpr bool
4808  operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
4809  { return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__proj)); }
4810  };
4811 
4812  inline constexpr __contains_fn contains{};
4813 
4814  struct __contains_subrange_fn
4815  {
4816  template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
4817  forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
4818  typename _Pred = ranges::equal_to,
4819  typename _Proj1 = identity, typename _Proj2 = identity>
4820  requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
4821  constexpr bool
4822  operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
4823  _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4824  {
4825  return __first2 == __last2
4826  || !ranges::search(__first1, __last1, __first2, __last2,
4827  std::move(__pred), std::move(__proj1), std::move(__proj2)).empty();
4828  }
4829 
4830  template<forward_range _Range1, forward_range _Range2,
4831  typename _Pred = ranges::equal_to,
4832  typename _Proj1 = identity, typename _Proj2 = identity>
4833  requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
4834  _Pred, _Proj1, _Proj2>
4835  constexpr bool
4836  operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
4837  _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
4838  {
4839  return (*this)(ranges::begin(__r1), ranges::end(__r1),
4840  ranges::begin(__r2), ranges::end(__r2),
4841  std::move(__pred), std::move(__proj1), std::move(__proj2));
4842  }
4843  };
4844 
4845  inline constexpr __contains_subrange_fn contains_subrange{};
4846 
4847 #endif // __glibcxx_ranges_contains
4848 
4849 #if __glibcxx_ranges_find_last >= 202207L // C++ >= 23
4850 
4851  struct __find_last_fn
4852  {
4853  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent,
4854  typename _Proj = identity,
4855  typename _Tp _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(_Iter, _Proj)>
4856  requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Tp*>
4857  [[nodiscard]] constexpr subrange<_Iter>
4858  operator()(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const
4859  {
4860  if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
4861  {
4862  _Iter __found = ranges::find(reverse_iterator<_Iter>{__last},
4863  reverse_iterator<_Iter>{__first},
4864  __value, std::move(__proj)).base();
4865  if (__found == __first)
4866  return {__last, __last};
4867  else
4868  return {ranges::prev(__found), __last};
4869  }
4870  else
4871  {
4872  _Iter __found = ranges::find(__first, __last, __value, __proj);
4873  if (__found == __last)
4874  return {__found, __found};
4875  __first = __found;
4876  for (;;)
4877  {
4878  __first = ranges::find(ranges::next(__first), __last, __value, __proj);
4879  if (__first == __last)
4880  return {__found, __first};
4881  __found = __first;
4882  }
4883  }
4884  }
4885 
4886  template<forward_range _Range, typename _Proj = identity,
4887  typename _Tp
4888  _GLIBCXX26_RANGE_ALGO_DEF_VAL_T(iterator_t<_Range>, _Proj)>
4889  requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Tp*>
4890  [[nodiscard]] constexpr borrowed_subrange_t<_Range>
4891  operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
4892  { return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__proj)); }
4893  };
4894 
4895  inline constexpr __find_last_fn find_last{};
4896 
4897  struct __find_last_if_fn
4898  {
4899  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Proj = identity,
4900  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
4901  [[nodiscard]] constexpr subrange<_Iter>
4902  operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const
4903  {
4904  if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
4905  {
4906  _Iter __found = ranges::find_if(reverse_iterator<_Iter>{__last},
4907  reverse_iterator<_Iter>{__first},
4908  std::move(__pred), std::move(__proj)).base();
4909  if (__found == __first)
4910  return {__last, __last};
4911  else
4912  return {ranges::prev(__found), __last};
4913  }
4914  else
4915  {
4916  _Iter __found = ranges::find_if(__first, __last, __pred, __proj);
4917  if (__found == __last)
4918  return {__found, __found};
4919  __first = __found;
4920  for (;;)
4921  {
4922  __first = ranges::find_if(ranges::next(__first), __last, __pred, __proj);
4923  if (__first == __last)
4924  return {__found, __first};
4925  __found = __first;
4926  }
4927  }
4928  }
4929 
4930  template<forward_range _Range, typename _Proj = identity,
4931  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
4932  [[nodiscard]] constexpr borrowed_subrange_t<_Range>
4933  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
4934  { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); }
4935  };
4936 
4937  inline constexpr __find_last_if_fn find_last_if{};
4938 
4939  struct __find_last_if_not_fn
4940  {
4941  template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Proj = identity,
4942  indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
4943  [[nodiscard]] constexpr subrange<_Iter>
4944  operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const
4945  {
4946  if constexpr (same_as<_Iter, _Sent> && bidirectional_iterator<_Iter>)
4947  {
4948  _Iter __found = ranges::find_if_not(reverse_iterator<_Iter>{__last},
4949  reverse_iterator<_Iter>{__first},
4950  std::move(__pred), std::move(__proj)).base();
4951  if (__found == __first)
4952  return {__last, __last};
4953  else
4954  return {ranges::prev(__found), __last};
4955  }
4956  else
4957  {
4958  _Iter __found = ranges::find_if_not(__first, __last, __pred, __proj);
4959  if (__found == __last)
4960  return {__found, __found};
4961  __first = __found;
4962  for (;;)
4963  {
4964  __first = ranges::find_if_not(ranges::next(__first), __last, __pred, __proj);
4965  if (__first == __last)
4966  return {__found, __first};
4967  __found = __first;
4968  }
4969  }
4970  }
4971 
4972  template<forward_range _Range, typename _Proj = identity,
4973  indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
4974  [[nodiscard]] constexpr borrowed_subrange_t<_Range>
4975  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
4976  { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); }
4977  };
4978 
4979  inline constexpr __find_last_if_not_fn find_last_if_not{};
4980 
4981 #endif // __glibcxx_ranges_find_last
4982 
4983 #if __glibcxx_ranges_fold >= 202207L // C++ >= 23
4984 
4985  template<typename _Iter, typename _Tp>
4986  struct in_value_result
4987  {
4988  [[no_unique_address]] _Iter in;
4989  [[no_unique_address]] _Tp value;
4990 
4991  template<typename _Iter2, typename _Tp2>
4992  requires convertible_to<const _Iter&, _Iter2>
4993  && convertible_to<const _Tp&, _Tp2>
4994  constexpr
4995  operator in_value_result<_Iter2, _Tp2>() const &
4996  { return {in, value}; }
4997 
4998  template<typename _Iter2, typename _Tp2>
4999  requires convertible_to<_Iter, _Iter2>
5000  && convertible_to<_Tp, _Tp2>
5001  constexpr
5002  operator in_value_result<_Iter2, _Tp2>() &&
5003  { return {std::move(in), std::move(value)}; }
5004  };
5005 
5006  namespace __detail
5007  {
5008  template<typename _Fp>
5009  class __flipped
5010  {
5011  _Fp _M_f;
5012 
5013  public:
5014  template<typename _Tp, typename _Up>
5015  requires invocable<_Fp&, _Up, _Tp>
5016  invoke_result_t<_Fp&, _Up, _Tp>
5017  operator()(_Tp&&, _Up&&); // not defined
5018  };
5019 
5020  template<typename _Fp, typename _Tp, typename _Iter, typename _Up>
5021  concept __indirectly_binary_left_foldable_impl = movable<_Tp> && movable<_Up>
5022  && convertible_to<_Tp, _Up>
5023  && invocable<_Fp&, _Up, iter_reference_t<_Iter>>
5024  && assignable_from<_Up&, invoke_result_t<_Fp&, _Up, iter_reference_t<_Iter>>>;
5025 
5026  template<typename _Fp, typename _Tp, typename _Iter>
5027  concept __indirectly_binary_left_foldable = copy_constructible<_Fp>
5028  && indirectly_readable<_Iter>
5029  && invocable<_Fp&, _Tp, iter_reference_t<_Iter>>
5030  && convertible_to<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Iter>>,
5031  decay_t<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Iter>>>>
5032  && __indirectly_binary_left_foldable_impl
5033  <_Fp, _Tp, _Iter, decay_t<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Iter>>>>;
5034 
5035  template <typename _Fp, typename _Tp, typename _Iter>
5036  concept __indirectly_binary_right_foldable
5037  = __indirectly_binary_left_foldable<__flipped<_Fp>, _Tp, _Iter>;
5038  } // namespace __detail
5039 
5040  template<typename _Iter, typename _Tp>
5041  using fold_left_with_iter_result = in_value_result<_Iter, _Tp>;
5042 
5043  struct __fold_left_with_iter_fn
5044  {
5045  template<typename _Ret_iter,
5046  typename _Iter, typename _Sent, typename _Tp, typename _Fp>
5047  static constexpr auto
5048  _S_impl(_Iter __first, _Sent __last, _Tp __init, _Fp __f)
5049  {
5050  using _Up = decay_t<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Iter>>>;
5051  using _Ret = fold_left_with_iter_result<_Ret_iter, _Up>;
5052 
5053  if (__first == __last)
5054  return _Ret{std::move(__first), _Up(std::move(__init))};
5055 
5056  _Up __accum = std::__invoke(__f, std::move(__init), *__first);
5057  for (++__first; __first != __last; ++__first)
5058  __accum = std::__invoke(__f, std::move(__accum), *__first);
5059  return _Ret{std::move(__first), std::move(__accum)};
5060  }
5061 
5062  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
5063  typename _Tp _GLIBCXX26_DEF_VAL_T(iter_value_t<_Iter>),
5064  __detail::__indirectly_binary_left_foldable<_Tp, _Iter> _Fp>
5065  constexpr auto
5066  operator()(_Iter __first, _Sent __last, _Tp __init, _Fp __f) const
5067  {
5068  using _Ret_iter = _Iter;
5069  return _S_impl<_Ret_iter>(std::move(__first), __last,
5070  std::move(__init), std::move(__f));
5071  }
5072 
5073  template<input_range _Range,
5074  typename _Tp _GLIBCXX26_DEF_VAL_T(range_value_t<_Range>),
5075  __detail::__indirectly_binary_left_foldable<_Tp, iterator_t<_Range>> _Fp>
5076  constexpr auto
5077  operator()(_Range&& __r, _Tp __init, _Fp __f) const
5078  {
5079  using _Ret_iter = borrowed_iterator_t<_Range>;
5080  return _S_impl<_Ret_iter>(ranges::begin(__r), ranges::end(__r),
5081  std::move(__init), std::move(__f));
5082  }
5083  };
5084 
5085  inline constexpr __fold_left_with_iter_fn fold_left_with_iter{};
5086 
5087  struct __fold_left_fn
5088  {
5089  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
5090  typename _Tp _GLIBCXX26_DEF_VAL_T(iter_value_t<_Iter>),
5091  __detail::__indirectly_binary_left_foldable<_Tp, _Iter> _Fp>
5092  constexpr auto
5093  operator()(_Iter __first, _Sent __last, _Tp __init, _Fp __f) const
5094  {
5095  return ranges::fold_left_with_iter(std::move(__first), __last,
5096  std::move(__init), std::move(__f)).value;
5097  }
5098 
5099  template<input_range _Range,
5100  typename _Tp _GLIBCXX26_DEF_VAL_T(range_value_t<_Range>),
5101  __detail::__indirectly_binary_left_foldable<_Tp, iterator_t<_Range>> _Fp>
5102  constexpr auto
5103  operator()(_Range&& __r, _Tp __init, _Fp __f) const
5104  { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__init), std::move(__f)); }
5105  };
5106 
5107  inline constexpr __fold_left_fn fold_left{};
5108 
5109  template<typename _Iter, typename _Tp>
5110  using fold_left_first_with_iter_result = in_value_result<_Iter, _Tp>;
5111 
5112  struct __fold_left_first_with_iter_fn
5113  {
5114  template<typename _Ret_iter, typename _Iter, typename _Sent, typename _Fp>
5115  static constexpr auto
5116  _S_impl(_Iter __first, _Sent __last, _Fp __f)
5117  {
5118  using _Up = decltype(ranges::fold_left(std::move(__first), __last,
5119  iter_value_t<_Iter>(*__first), __f));
5120  using _Ret = fold_left_first_with_iter_result<_Ret_iter, optional<_Up>>;
5121 
5122  if (__first == __last)
5123  return _Ret{std::move(__first), optional<_Up>()};
5124 
5125  optional<_Up> __init(in_place, *__first);
5126  for (++__first; __first != __last; ++__first)
5127  *__init = std::__invoke(__f, std::move(*__init), *__first);
5128  return _Ret{std::move(__first), std::move(__init)};
5129  }
5130 
5131  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
5132  __detail::__indirectly_binary_left_foldable<iter_value_t<_Iter>, _Iter> _Fp>
5133  requires constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>>
5134  constexpr auto
5135  operator()(_Iter __first, _Sent __last, _Fp __f) const
5136  {
5137  using _Ret_iter = _Iter;
5138  return _S_impl<_Ret_iter>(std::move(__first), __last, std::move(__f));
5139  }
5140 
5141  template<input_range _Range,
5142  __detail::__indirectly_binary_left_foldable<range_value_t<_Range>, iterator_t<_Range>> _Fp>
5143  requires constructible_from<range_value_t<_Range>, range_reference_t<_Range>>
5144  constexpr auto
5145  operator()(_Range&& __r, _Fp __f) const
5146  {
5147  using _Ret_iter = borrowed_iterator_t<_Range>;
5148  return _S_impl<_Ret_iter>(ranges::begin(__r), ranges::end(__r), std::move(__f));
5149  }
5150  };
5151 
5152  inline constexpr __fold_left_first_with_iter_fn fold_left_first_with_iter{};
5153 
5154  struct __fold_left_first_fn
5155  {
5156  template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
5157  __detail::__indirectly_binary_left_foldable<iter_value_t<_Iter>, _Iter> _Fp>
5158  requires constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>>
5159  constexpr auto
5160  operator()(_Iter __first, _Sent __last, _Fp __f) const
5161  {
5162  return ranges::fold_left_first_with_iter(std::move(__first), __last,
5163  std::move(__f)).value;
5164  }
5165 
5166  template<input_range _Range,
5167  __detail::__indirectly_binary_left_foldable<range_value_t<_Range>, iterator_t<_Range>> _Fp>
5168  requires constructible_from<range_value_t<_Range>, range_reference_t<_Range>>
5169  constexpr auto
5170  operator()(_Range&& __r, _Fp __f) const
5171  { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__f)); }
5172  };
5173 
5174  inline constexpr __fold_left_first_fn fold_left_first{};
5175 
5176  struct __fold_right_fn
5177  {
5178  template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
5179  typename _Tp _GLIBCXX26_DEF_VAL_T(iter_value_t<_Iter>),
5180  __detail::__indirectly_binary_right_foldable<_Tp, _Iter> _Fp>
5181  constexpr auto
5182  operator()(_Iter __first, _Sent __last, _Tp __init, _Fp __f) const
5183  {
5184  using _Up = decay_t<invoke_result_t<_Fp&, iter_reference_t<_Iter>, _Tp>>;
5185 
5186  if (__first == __last)
5187  return _Up(std::move(__init));
5188 
5189  _Iter __tail = ranges::next(__first, __last);
5190  _Up __accum = std::__invoke(__f, *--__tail, std::move(__init));
5191  while (__first != __tail)
5192  __accum = std::__invoke(__f, *--__tail, std::move(__accum));
5193  return __accum;
5194  }
5195 
5196  template<bidirectional_range _Range,
5197  typename _Tp _GLIBCXX26_DEF_VAL_T(range_value_t<_Range>),
5198  __detail::__indirectly_binary_right_foldable<_Tp, iterator_t<_Range>> _Fp>
5199  constexpr auto
5200  operator()(_Range&& __r, _Tp __init, _Fp __f) const
5201  { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__init), std::move(__f)); }
5202  };
5203 
5204  inline constexpr __fold_right_fn fold_right{};
5205 
5206  struct __fold_right_last_fn
5207  {
5208  template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
5209  __detail::__indirectly_binary_right_foldable<iter_value_t<_Iter>, _Iter> _Fp>
5210  requires constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>>
5211  constexpr auto
5212  operator()(_Iter __first, _Sent __last, _Fp __f) const
5213  {
5214  using _Up = decltype(ranges::fold_right(__first, __last,
5215  iter_value_t<_Iter>(*__first), __f));
5216 
5217  if (__first == __last)
5218  return optional<_Up>();
5219 
5220  _Iter __tail = ranges::prev(ranges::next(__first, std::move(__last)));
5221  return optional<_Up>(in_place,
5222  ranges::fold_right(std::move(__first), __tail,
5223  iter_value_t<_Iter>(*__tail),
5224  std::move(__f)));
5225  }
5226 
5227  template<bidirectional_range _Range,
5228  __detail::__indirectly_binary_right_foldable<range_value_t<_Range>, iterator_t<_Range>> _Fp>
5229  requires constructible_from<range_value_t<_Range>, range_reference_t<_Range>>
5230  constexpr auto
5231  operator()(_Range&& __r, _Fp __f) const
5232  { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__f)); }
5233  };
5234 
5235  inline constexpr __fold_right_last_fn fold_right_last{};
5236 #endif // __glibcxx_ranges_fold
5237 } // namespace ranges
5238 
5239 #if __glibcxx_shift >= 201806L // C++ >= 20
5240  template<typename _ForwardIterator>
5241  constexpr _ForwardIterator
5242  shift_left(_ForwardIterator __first, _ForwardIterator __last,
5243  typename iterator_traits<_ForwardIterator>::difference_type __n)
5244  {
5245  __glibcxx_assert(__n >= 0);
5246  if (__n == 0)
5247  return __last;
5248 
5249  auto __mid = ranges::next(__first, __n, __last);
5250  if (__mid == __last)
5251  return __first;
5252  return std::move(std::move(__mid), std::move(__last), std::move(__first));
5253  }
5254 
5255  template<typename _ForwardIterator>
5256  constexpr _ForwardIterator
5257  shift_right(_ForwardIterator __first, _ForwardIterator __last,
5258  typename iterator_traits<_ForwardIterator>::difference_type __n)
5259  {
5260  __glibcxx_assert(__n >= 0);
5261  if (__n == 0)
5262  return __first;
5263 
5264  using _Cat
5265  = typename iterator_traits<_ForwardIterator>::iterator_category;
5266  if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5267  {
5268  auto __mid = ranges::next(__last, -__n, __first);
5269  if (__mid == __first)
5270  return __last;
5271 
5272  return std::move_backward(std::move(__first), std::move(__mid),
5273  std::move(__last));
5274  }
5275  else
5276  {
5277  auto __result = ranges::next(__first, __n, __last);
5278  if (__result == __last)
5279  return __last;
5280 
5281  auto __dest_head = __first, __dest_tail = __result;
5282  while (__dest_head != __result)
5283  {
5284  if (__dest_tail == __last)
5285  {
5286  // If we get here, then we must have
5287  // 2*n >= distance(__first, __last)
5288  // i.e. we are shifting out at least half of the range. In
5289  // this case we can safely perform the shift with a single
5290  // move.
5291  std::move(std::move(__first), std::move(__dest_head), __result);
5292  return __result;
5293  }
5294  ++__dest_head;
5295  ++__dest_tail;
5296  }
5297 
5298  for (;;)
5299  {
5300  // At the start of each iteration of this outer loop, the range
5301  // [__first, __result) contains those elements that after shifting
5302  // the whole range right by __n, should end up in
5303  // [__dest_head, __dest_tail) in order.
5304 
5305  // The below inner loop swaps the elements of [__first, __result)
5306  // and [__dest_head, __dest_tail), while simultaneously shifting
5307  // the latter range by __n.
5308  auto __cursor = __first;
5309  while (__cursor != __result)
5310  {
5311  if (__dest_tail == __last)
5312  {
5313  // At this point the ranges [__first, result) and
5314  // [__dest_head, dest_tail) are disjoint, so we can safely
5315  // move the remaining elements.
5316  __dest_head = std::move(__cursor, __result,
5317  std::move(__dest_head));
5318  std::move(std::move(__first), std::move(__cursor),
5319  std::move(__dest_head));
5320  return __result;
5321  }
5322  std::iter_swap(__cursor, __dest_head);
5323  ++__dest_head;
5324  ++__dest_tail;
5325  ++__cursor;
5326  }
5327  }
5328  }
5329  }
5330 #endif
5331 
5332 namespace ranges
5333 {
5334 #if __glibcxx_shift >= 202202L // C++ >= 23
5335  struct __shift_left_fn
5336  {
5337  template<permutable _Iter, sentinel_for<_Iter> _Sent>
5338  constexpr subrange<_Iter>
5339  operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __n) const
5340  {
5341  __glibcxx_assert(__n >= 0);
5342  if (__n == 0)
5343  return {__first, ranges::next(__first, __last)};
5344 
5345  auto __mid = ranges::next(__first, __n, __last);
5346  if (__mid == __last)
5347  return {__first, __first};
5348  return {__first, ranges::move(__mid, __last, __first).out};
5349  }
5350 
5351  template<forward_range _Range>
5352  requires permutable<iterator_t<_Range>>
5353  constexpr borrowed_subrange_t<_Range>
5354  operator()(_Range&& __r, range_difference_t<_Range> __n) const
5355  { return (*this)(ranges::begin(__r), ranges::end(__r), __n); }
5356  };
5357 
5358  inline constexpr __shift_left_fn shift_left{};
5359 
5360  struct __shift_right_fn
5361  {
5362  template<permutable _Iter, sentinel_for<_Iter> _Sent>
5363  constexpr subrange<_Iter>
5364  operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __n) const
5365  {
5366  __glibcxx_assert(__n >= 0);
5367  if (__n == 0)
5368  return {__first, ranges::next(__first, __last)};
5369 
5370  if constexpr (bidirectional_iterator<_Iter> && same_as<_Iter, _Sent>)
5371  {
5372  auto __mid = ranges::next(__last, -__n, __first);
5373  if (__mid == __first)
5374  return {__last, __last};
5375 
5376  return {ranges::move_backward(__first, __mid, __last).out, __last};
5377  }
5378  else
5379  {
5380  auto __result = ranges::next(__first, __n, __last);
5381  if (__result == __last)
5382  return {__result, __result};
5383 
5384  auto __dest_head = __first, __dest_tail = __result;
5385  while (__dest_head != __result)
5386  {
5387  if (__dest_tail == __last)
5388  {
5389  // If we get here, then we must have
5390  // 2*n >= distance(__first, __last)
5391  // i.e. we are shifting out at least half of the range. In
5392  // this case we can safely perform the shift with a single
5393  // move.
5394  auto __lasti = ranges::move(__first, __dest_head, __result).out;
5395  // __glibcxx_assert(__lasti == __last);
5396  return {__result, __lasti};
5397  }
5398  ++__dest_head;
5399  ++__dest_tail;
5400  }
5401 
5402  for (;;)
5403  {
5404  // At the start of each iteration of this outer loop, the range
5405  // [__first, __result) contains those elements that after shifting
5406  // the whole range right by __n, should end up in
5407  // [__dest_head, __dest_tail) in order.
5408 
5409  // The below inner loop swaps the elements of [__first, __result)
5410  // and [__dest_head, __dest_tail), while simultaneously shifting
5411  // the latter range by __n.
5412  auto __cursor = __first;
5413  while (__cursor != __result)
5414  {
5415  if (__dest_tail == __last)
5416  {
5417  // At this point the ranges [__first, result) and
5418  // [__dest_head, dest_tail) are disjoint, so we can safely
5419  // move the remaining elements.
5420  __dest_head = ranges::move(__cursor, __result, __dest_head).out;
5421  auto __lasti = ranges::move(__first, __cursor, __dest_head).out;
5422  // __glibcxx_assert(__lasti == __last);
5423  return {__result, __lasti};
5424  }
5425  ranges::iter_swap(__cursor, __dest_head);
5426  ++__dest_head;
5427  ++__dest_tail;
5428  ++__cursor;
5429  }
5430  }
5431  }
5432  }
5433 
5434  template<forward_range _Range>
5435  requires permutable<iterator_t<_Range>>
5436  constexpr borrowed_subrange_t<_Range>
5437  operator()(_Range&& __r, range_difference_t<_Range> __n) const
5438  { return (*this)(ranges::begin(__r), ranges::end(__r), __n); }
5439  };
5440 
5441  inline constexpr __shift_right_fn shift_right{};
5442 #endif // C++23
5443 } // namespace ranges
5444 
5445 _GLIBCXX_END_NAMESPACE_VERSION
5446 } // namespace std
5447 #endif // concepts
5448 #endif // C++20
5449 #endif // _RANGES_ALGO_H
concept bidirectional_range
A range for which ranges::begin returns a bidirectional iterator.
Definition: ranges_base.h:611
concept forward_range
A range for which ranges::begin returns a forward iterator.
Definition: ranges_base.h:606
concept input_range
A range for which ranges::begin returns an input iterator.
Definition: ranges_base.h:601
concept random_access_range
A range for which ranges::begin returns a random access iterator.
Definition: ranges_base.h:616
requires requires
Definition: complex:1948
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
Definition: type_traits:2954
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:92
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:138
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:72
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
Definition: valarray:1251
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
Definition: valarray:1229
constexpr _BI2 move_backward(_BI1 __first, _BI1 __last, _BI2 __result)
Moves the range [first,last) into result.
Definition: stl_algobase.h:871
constexpr _InputIterator for_each_n(_InputIterator __first, _Size __n, _Function __f)
Apply a function to every element of a sequence.
Definition: stl_algo.h:3795
constexpr const _Tp & clamp(const _Tp &, const _Tp &, const _Tp &)
Returns the value clamped between lo and hi.
Definition: stl_algo.h:3614
constexpr const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
Definition: stl_algobase.h:256
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:3287
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
Definition: stl_algobase.h:232
constexpr reverse_iterator< _Iterator > make_reverse_iterator(_Iterator __i)
Generator function for reverse_iterator.
ISO C++ entities toplevel namespace is std.
_BidirectionalIterator1 __rotate_adaptive(_BidirectionalIterator1 __first, _BidirectionalIterator1 __middle, _BidirectionalIterator1 __last, _Distance __len1, _Distance __len2, _BidirectionalIterator2 __buffer, _Distance __buffer_size)
This is a helper function for the merge routines.
Definition: stl_algo.h:2323
concept weakly_incrementable
Requirements on types that can be incremented with ++.
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
void __merge_adaptive(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Compare __comp)
This is a helper function for the merge routines.
Definition: stl_algo.h:2361
constexpr _InputIterator __find_if_not_n(_InputIterator __first, _Distance &__len, _Predicate __pred)
Like find_if_not(), but uses and updates a count of the remaining range length instead of comparing a...
Definition: stl_algo.h:125
_GLIBCXX26_CONSTEXPR void __merge_without_buffer(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Distance __len1, _Distance __len2, _Compare __comp)
This is a helper function for the merge routines.
Definition: stl_algo.h:2436
concept copy_constructible
[concept.copyconstructible], concept copy_constructible
Definition: concepts:181
void __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
This is a helper function for the __merge_adaptive routines.
Definition: stl_algo.h:2254
_SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last, _SampleIterator __out, _Distance __n, _UniformRandomBitGenerator &&__g)
Take a random sample from a population.
Definition: stl_algo.h:5865
constexpr default_sentinel_t default_sentinel
A default sentinel value.
constexpr void __move_median_to_first(_Iterator __result, _Iterator __a, _Iterator __b, _Iterator __c, _Compare __comp)
Swaps the median value of *__a, *__b and *__c under __comp to *__result.
Definition: stl_algo.h:88
concept indirectly_comparable
[alg.req.ind.cmp], concept indirectly_comparable
pair< _IntType, _IntType > __gen_two_uniform_ints(_IntType __b0, _IntType __b1, _UniformRandomBitGenerator &&__g)
Generate two uniformly distributed integers using a single distribution invocation.
Definition: stl_algo.h:3664
void __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BidirectionalIterator3 __result, _Compare __comp)
This is a helper function for the __merge_adaptive routines.
Definition: stl_algo.h:2280
_GLIBCXX26_CONSTEXPR _ForwardIterator __stable_partition_adaptive(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, _Distance __len, _Pointer __buffer, _Distance __buffer_size)
This is a helper function... Requires __first != __last and !__pred(*__first) and __len == distance(_...
Definition: stl_algo.h:1452
_GLIBCXX26_CONSTEXPR void __inplace_stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
This is a helper function for the stable sorting routines.
Definition: stl_algo.h:2749
_OutputIterator __move_merge(_InputIterator __first1, _InputIterator __last1, _InputIterator __first2, _InputIterator __last2, _OutputIterator __result, _Compare __comp)
This is a helper function for the __merge_sort_loop routines.
Definition: stl_algo.h:2612
concept indirectly_writable
Requirements for writing a value into an iterator's referenced object.
Uniform discrete distribution for random numbers. A discrete random distribution on the range with e...