Home | History | Annotate | Line # | Download | only in std
      1 // <numeric> -*- C++ -*-
      2 
      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.
     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 /*
     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  */
     50 
     51 /** @file include/numeric
     52  *  This is a Standard C++ Library header.
     53  */
     54 
     55 #ifndef _GLIBCXX_NUMERIC
     56 #define _GLIBCXX_NUMERIC 1
     57 
     58 #pragma GCC system_header
     59 
     60 #include <bits/c++config.h>
     61 #include <bits/stl_iterator_base_types.h>
     62 #include <bits/stl_numeric.h>
     63 
     64 #ifdef _GLIBCXX_PARALLEL
     65 # include <parallel/numeric>
     66 #endif
     67 
     68 #if __cplusplus >= 201402L
     69 # include <type_traits>
     70 # include <bit>
     71 # include <ext/numeric_traits.h>
     72 #endif
     73 
     74 #if __cplusplus >= 201703L
     75 # include <bits/stl_function.h>
     76 #endif
     77 
     78 #if __cplusplus > 201703L
     79 # include <limits>
     80 #endif
     81 
     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>
     91 
     92 #if __glibcxx_ranges_iota >= 202202L // C++ >= 23
     93 # include <bits/ranges_algobase.h> // for ranges::iota
     94 #endif
     95 
     96 #ifdef __glibcxx_saturation_arithmetic // C++ >= 26
     97 # include <bits/sat_arith.h>
     98 #endif
     99 
    100 /**
    101  * @defgroup numerics Numerics
    102  *
    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  */
    107 
    108 namespace std _GLIBCXX_VISIBILITY(default)
    109 {
    110 _GLIBCXX_BEGIN_NAMESPACE_VERSION
    111 
    112 #if __cplusplus >= 201402L
    113 namespace __detail
    114 {
    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");
    123 
    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     }
    132 
    133   template<typename> void __abs_r(bool) = delete;
    134 
    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");
    141 
    142       if (__m == 0)
    143 	return __n;
    144       if (__n == 0)
    145 	return __m;
    146 
    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)
    152 
    153       while (true)
    154 	{
    155 	  if (__m > __n)
    156 	    {
    157 	      _Tp __tmp = __m;
    158 	      __m = __n;
    159 	      __n = __tmp;
    160 	    }
    161 
    162 	  __n -= __m;
    163 
    164 	  if (__n == 0)
    165 	    return __m << __k;
    166 
    167 	  __n >>= std::__countr_zero(__n);
    168 	}
    169     }
    170 } // namespace __detail
    171 #endif // C++14
    172 
    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     }
    188 
    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);
    204 
    205       if constexpr (is_signed_v<_Ct>)
    206 	if (__is_constant_evaluated())
    207 	  return __r * __n2; // constant evaluation can detect overflow here.
    208 
    209       bool __overflow = __builtin_mul_overflow(__r, __n2, &__r);
    210       __glibcxx_assert(!__overflow);
    211       return __r;
    212     }
    213 
    214 #endif // __cpp_lib_gcd_lcm
    215 
    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>;
    228 
    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     }
    255 
    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
    264 
    265 #if __cplusplus >= 201703L
    266   /// @addtogroup numeric_ops
    267   /// @{
    268 
    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     }
    314 
    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<>()); }
    331 
    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     }
    351 
    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     }
    398 
    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     }
    424 
    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     }
    463 
    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 	  _Tp __v = std::move(__init);
    493 	  __init = __binary_op(__v, *__first);
    494 	  ++__first;
    495 	  *__result++ = std::move(__v);
    496 	}
    497       return __result;
    498     }
    499 
    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     }
    526 
    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     }
    557 
    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     }
    592 
    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<>()); }
    614 
    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     }
    653 
    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     }
    688 
    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     }
    729 
    730   /// @} group numeric_ops
    731 #endif // C++17
    732 
    733 _GLIBCXX_END_NAMESPACE_VERSION
    734 } // namespace std
    735 
    736 #if __cplusplus >= 201703L && _GLIBCXX_HOSTED
    737 // Parallel STL algorithms
    738 # if _PSTL_EXECUTION_POLICIES_DEFINED
    739 // If <execution> has already been included, pull in implementations
    740 #  include <pstl/glue_numeric_impl.h>
    741 # else
    742 // Otherwise just pull in forward declarations
    743 #  include <pstl/glue_numeric_defs.h>
    744 #  define _PSTL_NUMERIC_FORWARD_DECLARED 1
    745 # endif
    746 #endif // C++17
    747 
    748 #endif /* _GLIBCXX_NUMERIC */
    749