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