Handle 'NUM' in 'PUSH_INSERT_PASSES_WITHIN'
[official-gcc.git] / libstdc++-v3 / include / std / numeric
blob201bb8e74a121bba239e0799935e9e9467865954
1 // <numeric> -*- C++ -*-
3 // Copyright (C) 2001-2024 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
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.
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.
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/>.
26  *
27  * Copyright (c) 1994
28  * Hewlett-Packard Company
29  *
30  * Permission to use, copy, modify, distribute and sell this software
31  * and its documentation for any purpose is hereby granted without fee,
32  * provided that the above copyright notice appear in all copies and
33  * that both that copyright notice and this permission notice appear
34  * in supporting documentation.  Hewlett-Packard Company makes no
35  * representations about the suitability of this software for any
36  * purpose.  It is provided "as is" without express or implied warranty.
37  *
38  *
39  * Copyright (c) 1996,1997
40  * Silicon Graphics Computer Systems, Inc.
41  *
42  * Permission to use, copy, modify, distribute and sell this software
43  * and its documentation for any purpose is hereby granted without fee,
44  * provided that the above copyright notice appear in all copies and
45  * that both that copyright notice and this permission notice appear
46  * in supporting documentation.  Silicon Graphics makes no
47  * representations about the suitability of this software for any
48  * purpose.  It is provided "as is" without express or implied warranty.
49  */
51 /** @file include/numeric
52  *  This is a Standard C++ Library header.
53  */
55 #ifndef _GLIBCXX_NUMERIC
56 #define _GLIBCXX_NUMERIC 1
58 #pragma GCC system_header
60 #include <bits/c++config.h>
61 #include <bits/stl_iterator_base_types.h>
62 #include <bits/stl_numeric.h>
64 #ifdef _GLIBCXX_PARALLEL
65 # include <parallel/numeric>
66 #endif
68 #if __cplusplus >= 201402L
69 # include <type_traits>
70 # include <bit>
71 # include <ext/numeric_traits.h>
72 #endif
74 #if __cplusplus >= 201703L
75 # include <bits/stl_function.h>
76 #endif
78 #if __cplusplus > 201703L
79 # include <limits>
80 #endif
82 #define __glibcxx_want_constexpr_numeric
83 #define __glibcxx_want_gcd
84 #define __glibcxx_want_gcd_lcm
85 #define __glibcxx_want_interpolate
86 #define __glibcxx_want_lcm
87 #define __glibcxx_want_parallel_algorithm
88 #define __glibcxx_want_ranges_iota
89 #define __glibcxx_want_saturation_arithmetic
90 #include <bits/version.h>
92 #if __glibcxx_ranges_iota >= 202202L // C++ >= 23
93 # include <bits/ranges_algobase.h> // for ranges::out_value_result
94 #endif
96 #ifdef __glibcxx_saturation_arithmetic // C++ >= 26
97 # include <bits/sat_arith.h>
98 #endif
101  * @defgroup numerics Numerics
103  * Components for performing numeric operations. Includes support for
104  * complex number types, random number generation, numeric (n-at-a-time)
105  * arrays, generalized numeric algorithms, and mathematical special functions.
106  */
108 namespace std _GLIBCXX_VISIBILITY(default)
110 _GLIBCXX_BEGIN_NAMESPACE_VERSION
112 #if __cplusplus >= 201402L
113 namespace __detail
115   // Like std::abs, but supports unsigned types and returns the specified type,
116   // so |std::numeric_limits<_Tp>::min()| is OK if representable in _Res.
117   template<typename _Res, typename _Tp>
118     constexpr _Res
119     __abs_r(_Tp __val)
120     {
121       static_assert(sizeof(_Res) >= sizeof(_Tp),
122           "result type must be at least as wide as the input type");
124       if (__val >= 0)
125         return __val;
126 #ifdef _GLIBCXX_ASSERTIONS
127       if (!__is_constant_evaluated()) // overflow already detected in constexpr
128         __glibcxx_assert(__val != __gnu_cxx::__int_traits<_Res>::__min);
129 #endif
130       return -static_cast<_Res>(__val);
131     }
133   template<typename> void __abs_r(bool) = delete;
135   // GCD implementation, using Stein's algorithm
136   template<typename _Tp>
137     constexpr _Tp
138     __gcd(_Tp __m, _Tp __n)
139     {
140       static_assert(is_unsigned<_Tp>::value, "type must be unsigned");
142       if (__m == 0)
143         return __n;
144       if (__n == 0)
145         return __m;
147       const int __i = std::__countr_zero(__m);
148       __m >>= __i;
149       const int __j = std::__countr_zero(__n);
150       __n >>= __j;
151       const int __k = __i < __j ? __i : __j; // min(i, j)
153       while (true)
154         {
155           if (__m > __n)
156             {
157               _Tp __tmp = __m;
158               __m = __n;
159               __n = __tmp;
160             }
162           __n -= __m;
164           if (__n == 0)
165             return __m << __k;
167           __n >>= std::__countr_zero(__n);
168         }
169     }
170 } // namespace __detail
171 #endif // C++14
173 #ifdef __cpp_lib_gcd_lcm // C++ >= 17
174   /// Greatest common divisor
175   template<typename _Mn, typename _Nn>
176     constexpr common_type_t<_Mn, _Nn>
177     gcd(_Mn __m, _Nn __n) noexcept
178     {
179       static_assert(is_integral_v<_Mn> && is_integral_v<_Nn>,
180                     "std::gcd arguments must be integers");
181       static_assert(_Mn(2) == 2 && _Nn(2) == 2,
182                     "std::gcd arguments must not be bool");
183       using _Ct = common_type_t<_Mn, _Nn>;
184       const _Ct __m2 = __detail::__abs_r<_Ct>(__m);
185       const _Ct __n2 = __detail::__abs_r<_Ct>(__n);
186       return __detail::__gcd<make_unsigned_t<_Ct>>(__m2, __n2);
187     }
189   /// Least common multiple
190   template<typename _Mn, typename _Nn>
191     constexpr common_type_t<_Mn, _Nn>
192     lcm(_Mn __m, _Nn __n) noexcept
193     {
194       static_assert(is_integral_v<_Mn> && is_integral_v<_Nn>,
195                     "std::lcm arguments must be integers");
196       static_assert(_Mn(2) == 2 && _Nn(2) == 2,
197                     "std::lcm arguments must not be bool");
198       using _Ct = common_type_t<_Mn, _Nn>;
199       const _Ct __m2 = __detail::__abs_r<_Ct>(__m);
200       const _Ct __n2 = __detail::__abs_r<_Ct>(__n);
201       if (__m2 == 0 || __n2 == 0)
202         return 0;
203       _Ct __r = __m2 / __detail::__gcd<make_unsigned_t<_Ct>>(__m2, __n2);
205       if constexpr (is_signed_v<_Ct>)
206         if (__is_constant_evaluated())
207           return __r * __n2; // constant evaluation can detect overflow here.
209       bool __overflow = __builtin_mul_overflow(__r, __n2, &__r);
210       __glibcxx_assert(!__overflow);
211       return __r;
212     }
214 #endif // __cpp_lib_gcd_lcm
216   // midpoint
217 #ifdef __cpp_lib_interpolate // C++ >= 20
218   template<typename _Tp>
219     constexpr
220     enable_if_t<__and_v<is_arithmetic<_Tp>, is_same<remove_cv_t<_Tp>, _Tp>,
221                         __not_<is_same<_Tp, bool>>>,
222                 _Tp>
223     midpoint(_Tp __a, _Tp __b) noexcept
224     {
225       if constexpr (is_integral_v<_Tp>)
226         {
227           using _Up = make_unsigned_t<_Tp>;
229           int __k = 1;
230           _Up __m = __a;
231           _Up __M = __b;
232           if (__a > __b)
233             {
234               __k = -1;
235               __m = __b;
236               __M = __a;
237             }
238           return __a + __k * _Tp(_Up(__M - __m) / 2);
239         }
240       else // is_floating
241         {
242           constexpr _Tp __lo = numeric_limits<_Tp>::min() * 2;
243           constexpr _Tp __hi = numeric_limits<_Tp>::max() / 2;
244           const _Tp __abs_a = __a < 0 ? -__a : __a;
245           const _Tp __abs_b = __b < 0 ? -__b : __b;
246           if (__abs_a <= __hi && __abs_b <= __hi) [[likely]]
247             return (__a + __b) / 2; // always correctly rounded
248           if (__abs_a < __lo) // not safe to halve __a
249             return __a + __b/2;
250           if (__abs_b < __lo) // not safe to halve __b
251             return __a/2 + __b;
252           return __a/2 + __b/2;     // otherwise correctly rounded
253         }
254     }
256   template<typename _Tp>
257     constexpr enable_if_t<is_object_v<_Tp>, _Tp*>
258     midpoint(_Tp* __a, _Tp* __b) noexcept
259     {
260       static_assert( sizeof(_Tp) != 0, "type must be complete" );
261       return __a  + (__b - __a) / 2;
262     }
263 #endif // __cpp_lib_interpolate
265 #if __cplusplus >= 201703L
266   /// @addtogroup numeric_ops
267   /// @{
269   /**
270    *  @brief  Calculate reduction of values in a range.
271    *
272    *  @param  __first  Start of range.
273    *  @param  __last  End of range.
274    *  @param  __init  Starting value to add other values to.
275    *  @param  __binary_op A binary function object.
276    *  @return  The final sum.
277    *
278    *  Reduce the values in the range `[first,last)` using a binary operation.
279    *  The initial value is `init`.  The values are not necessarily processed
280    *  in order.
281    *
282    *  This algorithm is similar to `std::accumulate` but is not required to
283    *  perform the operations in order from first to last. For operations
284    *  that are commutative and associative the result will be the same as
285    *  for `std::accumulate`, but for other operations (such as floating point
286    *  arithmetic) the result can be different.
287    */
288   template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
289     _GLIBCXX20_CONSTEXPR
290     _Tp
291     reduce(_InputIterator __first, _InputIterator __last, _Tp __init,
292            _BinaryOperation __binary_op)
293     {
294       using __ref = typename iterator_traits<_InputIterator>::reference;
295       static_assert(is_invocable_r_v<_Tp, _BinaryOperation&, _Tp&, __ref>);
296       static_assert(is_invocable_r_v<_Tp, _BinaryOperation&, __ref, _Tp&>);
297       static_assert(is_invocable_r_v<_Tp, _BinaryOperation&, _Tp&, _Tp&>);
298       static_assert(is_invocable_r_v<_Tp, _BinaryOperation&, __ref, __ref>);
299       if constexpr (__is_random_access_iter<_InputIterator>::value)
300         {
301           while ((__last - __first) >= 4)
302             {
303               _Tp __v1 = __binary_op(__first[0], __first[1]);
304               _Tp __v2 = __binary_op(__first[2], __first[3]);
305               _Tp __v3 = __binary_op(__v1, __v2);
306               __init = __binary_op(__init, __v3);
307               __first += 4;
308             }
309         }
310       for (; __first != __last; ++__first)
311         __init = __binary_op(__init, *__first);
312       return __init;
313     }
315  /**
316    *  @brief  Calculate reduction of values in a range.
317    *
318    *  @param  __first  Start of range.
319    *  @param  __last  End of range.
320    *  @param  __init  Starting value to add other values to.
321    *  @return  The final sum.
322    *
323    *  Reduce the values in the range `[first,last)` using addition.
324    *  Equivalent to calling `std::reduce(first, last, init, std::plus<>())`.
325    */
326   template<typename _InputIterator, typename _Tp>
327     _GLIBCXX20_CONSTEXPR
328     inline _Tp
329     reduce(_InputIterator __first, _InputIterator __last, _Tp __init)
330     { return std::reduce(__first, __last, std::move(__init), plus<>()); }
332   /**
333    *  @brief  Calculate reduction of values in a range.
334    *
335    *  @param  __first  Start of range.
336    *  @param  __last  End of range.
337    *  @return  The final sum.
338    *
339    *  Reduce the values in the range `[first,last)` using addition, with
340    *  an initial value of `T{}`, where `T` is the iterator's value type.
341    *  Equivalent to calling `std::reduce(first, last, T{}, std::plus<>())`.
342    */
343   template<typename _InputIterator>
344     _GLIBCXX20_CONSTEXPR
345     inline typename iterator_traits<_InputIterator>::value_type
346     reduce(_InputIterator __first, _InputIterator __last)
347     {
348       using value_type = typename iterator_traits<_InputIterator>::value_type;
349       return std::reduce(__first, __last, value_type{}, plus<>());
350     }
352   /**
353    *  @brief  Combine elements from two ranges and reduce
354    *
355    *  @param  __first1  Start of first range.
356    *  @param  __last1  End of first range.
357    *  @param  __first2  Start of second range.
358    *  @param  __init  Starting value to add other values to.
359    *  @param  __binary_op1 The function used to perform reduction.
360    *  @param  __binary_op2 The function used to combine values from the ranges.
361    *  @return  The final sum.
362    *
363    *  Call `binary_op2(first1[n],first2[n])` for each `n` in `[0,last1-first1)`
364    *  and then use `binary_op1` to reduce the values returned by `binary_op2`
365    *  to a single value of type `T`.
366    *
367    *  The range beginning at `first2` must contain at least `last1-first1`
368    *  elements.
369    */
370   template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
371            typename _BinaryOperation1, typename _BinaryOperation2>
372     _GLIBCXX20_CONSTEXPR
373     _Tp
374     transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
375                      _InputIterator2 __first2, _Tp __init,
376                      _BinaryOperation1 __binary_op1,
377                      _BinaryOperation2 __binary_op2)
378     {
379       if constexpr (__and_v<__is_random_access_iter<_InputIterator1>,
380                             __is_random_access_iter<_InputIterator2>>)
381         {
382           while ((__last1 - __first1) >= 4)
383             {
384               _Tp __v1 = __binary_op1(__binary_op2(__first1[0], __first2[0]),
385                                       __binary_op2(__first1[1], __first2[1]));
386               _Tp __v2 = __binary_op1(__binary_op2(__first1[2], __first2[2]),
387                                       __binary_op2(__first1[3], __first2[3]));
388               _Tp __v3 = __binary_op1(__v1, __v2);
389               __init = __binary_op1(__init, __v3);
390               __first1 += 4;
391               __first2 += 4;
392             }
393         }
394       for (; __first1 != __last1; ++__first1, (void) ++__first2)
395         __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
396       return __init;
397     }
399   /**
400    *  @brief  Combine elements from two ranges and reduce
401    *
402    *  @param  __first1  Start of first range.
403    *  @param  __last1  End of first range.
404    *  @param  __first2  Start of second range.
405    *  @param  __init  Starting value to add other values to.
406    *  @return  The final sum.
407    *
408    *  Call `first1[n]*first2[n]` for each `n` in `[0,last1-first1)` and then
409    *  use addition to sum those products to a single value of type `T`.
410    *
411    *  The range beginning at `first2` must contain at least `last1-first1`
412    *  elements.
413    */
414   template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
415     _GLIBCXX20_CONSTEXPR
416     inline _Tp
417     transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
418                      _InputIterator2 __first2, _Tp __init)
419     {
420       return std::transform_reduce(__first1, __last1, __first2,
421                                    std::move(__init),
422                                    plus<>(), multiplies<>());
423     }
425   /**
426    *  @brief  Transform the elements of a range and reduce
427    *
428    *  @param  __first  Start of range.
429    *  @param  __last  End of range.
430    *  @param  __init  Starting value to add other values to.
431    *  @param  __binary_op The function used to perform reduction.
432    *  @param  __unary_op The function used to transform values from the range.
433    *  @return  The final sum.
434    *
435    *  Call `unary_op(first[n])` for each `n` in `[0,last-first)` and then
436    *  use `binary_op` to reduce the values returned by `unary_op`
437    *  to a single value of type `T`.
438    */
439   template<typename _InputIterator, typename _Tp,
440            typename _BinaryOperation, typename _UnaryOperation>
441     _GLIBCXX20_CONSTEXPR
442     _Tp
443     transform_reduce(_InputIterator __first, _InputIterator __last, _Tp __init,
444                      _BinaryOperation __binary_op, _UnaryOperation __unary_op)
445     {
446       if constexpr (__is_random_access_iter<_InputIterator>::value)
447         {
448           while ((__last - __first) >= 4)
449             {
450               _Tp __v1 = __binary_op(__unary_op(__first[0]),
451                                      __unary_op(__first[1]));
452               _Tp __v2 = __binary_op(__unary_op(__first[2]),
453                                      __unary_op(__first[3]));
454               _Tp __v3 = __binary_op(__v1, __v2);
455               __init = __binary_op(__init, __v3);
456               __first += 4;
457             }
458         }
459       for (; __first != __last; ++__first)
460         __init = __binary_op(__init, __unary_op(*__first));
461       return __init;
462     }
464   /** @brief Output the cumulative sum of one range to a second range
465    *
466    *  @param __first  Start of input range.
467    *  @param __last   End of input range.
468    *  @param __result Start of output range.
469    *  @param __init   Initial value.
470    *  @param __binary_op Function to perform summation.
471    *  @return The end of the output range.
472    *
473    *  Write the cumulative sum (aka prefix sum, aka scan) of the input range
474    *  to the output range. Each element of the output range contains the
475    *  running total of all earlier elements (and the initial value),
476    *  using `binary_op` for summation.
477    *
478    *  This function generates an "exclusive" scan, meaning the Nth element
479    *  of the output range is the sum of the first N-1 input elements,
480    *  so the Nth input element is not included.
481    */
482   template<typename _InputIterator, typename _OutputIterator, typename _Tp,
483            typename _BinaryOperation>
484     _GLIBCXX20_CONSTEXPR
485     _OutputIterator
486     exclusive_scan(_InputIterator __first, _InputIterator __last,
487                    _OutputIterator __result, _Tp __init,
488                    _BinaryOperation __binary_op)
489     {
490       while (__first != __last)
491         {
492           auto __v = __init;
493           __init = __binary_op(__init, *__first);
494           ++__first;
495           *__result++ = std::move(__v);
496         }
497       return __result;
498     }
500   /** @brief Output the cumulative sum of one range to a second range
501    *
502    *  @param __first  Start of input range.
503    *  @param __last   End of input range.
504    *  @param __result Start of output range.
505    *  @param __init   Initial value.
506    *  @return The end of the output range.
507    *
508    *  Write the cumulative sum (aka prefix sum, aka scan) of the input range
509    *  to the output range. Each element of the output range contains the
510    *  running total of all earlier elements (and the initial value),
511    *  using `std::plus<>` for summation.
512    *
513    *  This function generates an "exclusive" scan, meaning the Nth element
514    *  of the output range is the sum of the first N-1 input elements,
515    *  so the Nth input element is not included.
516    */
517   template<typename _InputIterator, typename _OutputIterator, typename _Tp>
518     _GLIBCXX20_CONSTEXPR
519     inline _OutputIterator
520     exclusive_scan(_InputIterator __first, _InputIterator __last,
521                    _OutputIterator __result, _Tp __init)
522     {
523       return std::exclusive_scan(__first, __last, __result, std::move(__init),
524                                  plus<>());
525     }
527   /** @brief Output the cumulative sum of one range to a second range
528    *
529    *  @param __first  Start of input range.
530    *  @param __last   End of input range.
531    *  @param __result Start of output range.
532    *  @param __binary_op Function to perform summation.
533    *  @param __init   Initial value.
534    *  @return The end of the output range.
535    *
536    *  Write the cumulative sum (aka prefix sum, aka scan) of the input range
537    *  to the output range. Each element of the output range contains the
538    *  running total of all earlier elements (and the initial value),
539    *  using `binary_op` for summation.
540    *
541    *  This function generates an "inclusive" scan, meaning the Nth element
542    *  of the output range is the sum of the first N input elements,
543    *  so the Nth input element is included.
544    */
545   template<typename _InputIterator, typename _OutputIterator,
546            typename _BinaryOperation, typename _Tp>
547     _GLIBCXX20_CONSTEXPR
548     _OutputIterator
549     inclusive_scan(_InputIterator __first, _InputIterator __last,
550                    _OutputIterator __result, _BinaryOperation __binary_op,
551                    _Tp __init)
552     {
553       for (; __first != __last; ++__first)
554         *__result++ = __init = __binary_op(__init, *__first);
555       return __result;
556     }
558   /** @brief Output the cumulative sum of one range to a second range
559    *
560    *  @param __first  Start of input range.
561    *  @param __last   End of input range.
562    *  @param __result Start of output range.
563    *  @param __binary_op Function to perform summation.
564    *  @return The end of the output range.
565    *
566    *  Write the cumulative sum (aka prefix sum, aka scan) of the input range
567    *  to the output range. Each element of the output range contains the
568    *  running total of all earlier elements, using `binary_op` for summation.
569    *
570    *  This function generates an "inclusive" scan, meaning the Nth element
571    *  of the output range is the sum of the first N input elements,
572    *  so the Nth input element is included.
573    */
574   template<typename _InputIterator, typename _OutputIterator,
575            typename _BinaryOperation>
576     _GLIBCXX20_CONSTEXPR
577     _OutputIterator
578     inclusive_scan(_InputIterator __first, _InputIterator __last,
579                    _OutputIterator __result, _BinaryOperation __binary_op)
580     {
581       if (__first != __last)
582         {
583           auto __init = *__first;
584           *__result++ = __init;
585           ++__first;
586           if (__first != __last)
587             __result = std::inclusive_scan(__first, __last, __result,
588                                            __binary_op, std::move(__init));
589         }
590       return __result;
591     }
593   /** @brief Output the cumulative sum of one range to a second range
594    *
595    *  @param __first  Start of input range.
596    *  @param __last   End of input range.
597    *  @param __result Start of output range.
598    *  @return The end of the output range.
599    *
600    *  Write the cumulative sum (aka prefix sum, aka scan) of the input range
601    *  to the output range. Each element of the output range contains the
602    *  running total of all earlier elements, using `std::plus<>` for summation.
603    *
604    *  This function generates an "inclusive" scan, meaning the Nth element
605    *  of the output range is the sum of the first N input elements,
606    *  so the Nth input element is included.
607    */
608   template<typename _InputIterator, typename _OutputIterator>
609     _GLIBCXX20_CONSTEXPR
610     inline _OutputIterator
611     inclusive_scan(_InputIterator __first, _InputIterator __last,
612                    _OutputIterator __result)
613     { return std::inclusive_scan(__first, __last, __result, plus<>()); }
615   /** @brief Output the cumulative sum of one range to a second range
616    *
617    *  @param __first  Start of input range.
618    *  @param __last   End of input range.
619    *  @param __result Start of output range.
620    *  @param __init   Initial value.
621    *  @param __binary_op Function to perform summation.
622    *  @param __unary_op Function to transform elements of the input range.
623    *  @return The end of the output range.
624    *
625    *  Write the cumulative sum (aka prefix sum, aka scan) of the input range
626    *  to the output range. Each element of the output range contains the
627    *  running total of all earlier elements (and the initial value),
628    *  using `__unary_op` to transform the input elements
629    *  and using `__binary_op` for summation.
630    *
631    *  This function generates an "exclusive" scan, meaning the Nth element
632    *  of the output range is the sum of the first N-1 input elements,
633    *  so the Nth input element is not included.
634    */
635   template<typename _InputIterator, typename _OutputIterator, typename _Tp,
636            typename _BinaryOperation, typename _UnaryOperation>
637     _GLIBCXX20_CONSTEXPR
638     _OutputIterator
639     transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
640                              _OutputIterator __result, _Tp __init,
641                              _BinaryOperation __binary_op,
642                              _UnaryOperation __unary_op)
643     {
644       while (__first != __last)
645         {
646           auto __v = __init;
647           __init = __binary_op(__init, __unary_op(*__first));
648           ++__first;
649           *__result++ = std::move(__v);
650         }
651       return __result;
652     }
654   /** @brief Output the cumulative sum of one range to a second range
655    *
656    *  @param __first  Start of input range.
657    *  @param __last   End of input range.
658    *  @param __result Start of output range.
659    *  @param __binary_op Function to perform summation.
660    *  @param __unary_op Function to transform elements of the input range.
661    *  @param __init   Initial value.
662    *  @return The end of the output range.
663    *
664    *  Write the cumulative sum (aka prefix sum, aka scan) of the input range
665    *  to the output range. Each element of the output range contains the
666    *  running total of all earlier elements (and the initial value),
667    *  using `__unary_op` to transform the input elements
668    *  and using `__binary_op` for summation.
669    *
670    *  This function generates an "inclusive" scan, meaning the Nth element
671    *  of the output range is the sum of the first N input elements,
672    *  so the Nth input element is included.
673    */
674   template<typename _InputIterator, typename _OutputIterator,
675            typename _BinaryOperation, typename _UnaryOperation, typename _Tp>
676     _GLIBCXX20_CONSTEXPR
677     _OutputIterator
678     transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
679                              _OutputIterator __result,
680                              _BinaryOperation __binary_op,
681                              _UnaryOperation __unary_op,
682                              _Tp __init)
683     {
684       for (; __first != __last; ++__first)
685         *__result++ = __init = __binary_op(__init, __unary_op(*__first));
686       return __result;
687     }
689   /** @brief Output the cumulative sum of one range to a second range
690    *
691    *  @param __first  Start of input range.
692    *  @param __last   End of input range.
693    *  @param __result Start of output range.
694    *  @param __binary_op Function to perform summation.
695    *  @param __unary_op Function to transform elements of the input range.
696    *  @return The end of the output range.
697    *
698    *  Write the cumulative sum (aka prefix sum, aka scan) of the input range
699    *  to the output range. Each element of the output range contains the
700    *  running total of all earlier elements,
701    *  using `__unary_op` to transform the input elements
702    *  and using `__binary_op` for summation.
703    *
704    *  This function generates an "inclusive" scan, meaning the Nth element
705    *  of the output range is the sum of the first N input elements,
706    *  so the Nth input element is included.
707    */
708   template<typename _InputIterator, typename _OutputIterator,
709           typename _BinaryOperation, typename _UnaryOperation>
710     _GLIBCXX20_CONSTEXPR
711     _OutputIterator
712     transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
713                              _OutputIterator __result,
714                              _BinaryOperation __binary_op,
715                              _UnaryOperation __unary_op)
716     {
717       if (__first != __last)
718         {
719           auto __init = __unary_op(*__first);
720           *__result++ = __init;
721           ++__first;
722           if (__first != __last)
723             __result = std::transform_inclusive_scan(__first, __last, __result,
724                                                      __binary_op, __unary_op,
725                                                      std::move(__init));
726         }
727       return __result;
728     }
730   /// @} group numeric_ops
731 #endif // C++17
733 namespace ranges
735 #if __glibcxx_ranges_iota >= 202202L // C++ >= 23
737   template<typename _Out, typename _Tp>
738   using iota_result = out_value_result<_Out, _Tp>;
740   struct __iota_fn
741   {
742     template<input_or_output_iterator _Out, sentinel_for<_Out> _Sent, weakly_incrementable _Tp>
743       requires indirectly_writable<_Out, const _Tp&>
744       constexpr iota_result<_Out, _Tp>
745       operator()(_Out __first, _Sent __last, _Tp __value) const
746       {
747         while (__first != __last)
748           {
749             *__first = static_cast<const _Tp&>(__value);
750             ++__first;
751             ++__value;
752           }
753         return {std::move(__first), std::move(__value)};
754       }
756     template<weakly_incrementable _Tp, output_range<const _Tp&> _Range>
757       constexpr iota_result<borrowed_iterator_t<_Range>, _Tp>
758       operator()(_Range&& __r, _Tp __value) const
759       { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__value)); }
760   };
762   inline constexpr __iota_fn iota{};
764 #endif // __glibcxx_ranges_iota
765 } // namespace ranges
767 _GLIBCXX_END_NAMESPACE_VERSION
768 } // namespace std
770 #if __cplusplus >= 201703L && _GLIBCXX_HOSTED
771 // Parallel STL algorithms
772 # if _PSTL_EXECUTION_POLICIES_DEFINED
773 // If <execution> has already been included, pull in implementations
774 #  include <pstl/glue_numeric_impl.h>
775 # else
776 // Otherwise just pull in forward declarations
777 #  include <pstl/glue_numeric_defs.h>
778 #  define _PSTL_NUMERIC_FORWARD_DECLARED 1
779 # endif
780 #endif // C++17
782 #endif /* _GLIBCXX_NUMERIC */