libstdc++
numeric
Go to the documentation of this file.
1 // <numeric> -*- C++ -*-
2 
3 // Copyright (C) 2001-2023 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /*
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 #if __cplusplus > 202002L
83 # include <bits/ranges_algobase.h> // for ranges::iota
84 #endif
85 
86 /**
87  * @defgroup numerics Numerics
88  *
89  * Components for performing numeric operations. Includes support for
90  * complex number types, random number generation, numeric (n-at-a-time)
91  * arrays, generalized numeric algorithms, and mathematical special functions.
92  */
93 
94 namespace std _GLIBCXX_VISIBILITY(default)
95 {
96 _GLIBCXX_BEGIN_NAMESPACE_VERSION
97 
98 #if __cplusplus >= 201402L
99 namespace __detail
100 {
101  // Like std::abs, but supports unsigned types and returns the specified type,
102  // so |std::numeric_limits<_Tp>::min()| is OK if representable in _Res.
103  template<typename _Res, typename _Tp>
104  constexpr _Res
105  __abs_r(_Tp __val)
106  {
107  static_assert(sizeof(_Res) >= sizeof(_Tp),
108  "result type must be at least as wide as the input type");
109 
110  if (__val >= 0)
111  return __val;
112 #ifdef _GLIBCXX_ASSERTIONS
113  if (!__is_constant_evaluated()) // overflow already detected in constexpr
114  __glibcxx_assert(__val != __gnu_cxx::__int_traits<_Res>::__min);
115 #endif
116  return -static_cast<_Res>(__val);
117  }
118 
119  template<typename> void __abs_r(bool) = delete;
120 
121  // GCD implementation, using Stein's algorithm
122  template<typename _Tp>
123  constexpr _Tp
124  __gcd(_Tp __m, _Tp __n)
125  {
126  static_assert(is_unsigned<_Tp>::value, "type must be unsigned");
127 
128  if (__m == 0)
129  return __n;
130  if (__n == 0)
131  return __m;
132 
133  const int __i = std::__countr_zero(__m);
134  __m >>= __i;
135  const int __j = std::__countr_zero(__n);
136  __n >>= __j;
137  const int __k = __i < __j ? __i : __j; // min(i, j)
138 
139  while (true)
140  {
141  if (__m > __n)
142  {
143  _Tp __tmp = __m;
144  __m = __n;
145  __n = __tmp;
146  }
147 
148  __n -= __m;
149 
150  if (__n == 0)
151  return __m << __k;
152 
153  __n >>= std::__countr_zero(__n);
154  }
155  }
156 } // namespace __detail
157 
158 #if __cplusplus >= 201703L
159 
160 #define __cpp_lib_gcd_lcm 201606L
161 // These were used in drafts of SD-6:
162 #define __cpp_lib_gcd 201606L
163 #define __cpp_lib_lcm 201606L
164 
165  /// Greatest common divisor
166  template<typename _Mn, typename _Nn>
167  constexpr common_type_t<_Mn, _Nn>
168  gcd(_Mn __m, _Nn __n) noexcept
169  {
170  static_assert(is_integral_v<_Mn> && is_integral_v<_Nn>,
171  "std::gcd arguments must be integers");
172  static_assert(_Mn(2) == 2 && _Nn(2) == 2,
173  "std::gcd arguments must not be bool");
174  using _Ct = common_type_t<_Mn, _Nn>;
175  const _Ct __m2 = __detail::__abs_r<_Ct>(__m);
176  const _Ct __n2 = __detail::__abs_r<_Ct>(__n);
177  return __detail::__gcd<make_unsigned_t<_Ct>>(__m2, __n2);
178  }
179 
180  /// Least common multiple
181  template<typename _Mn, typename _Nn>
182  constexpr common_type_t<_Mn, _Nn>
183  lcm(_Mn __m, _Nn __n) noexcept
184  {
185  static_assert(is_integral_v<_Mn> && is_integral_v<_Nn>,
186  "std::lcm arguments must be integers");
187  static_assert(_Mn(2) == 2 && _Nn(2) == 2,
188  "std::lcm arguments must not be bool");
189  using _Ct = common_type_t<_Mn, _Nn>;
190  const _Ct __m2 = __detail::__abs_r<_Ct>(__m);
191  const _Ct __n2 = __detail::__abs_r<_Ct>(__n);
192  if (__m2 == 0 || __n2 == 0)
193  return 0;
194  _Ct __r = __m2 / __detail::__gcd<make_unsigned_t<_Ct>>(__m2, __n2);
195 
196  if constexpr (is_signed_v<_Ct>)
197  if (__is_constant_evaluated())
198  return __r * __n2; // constant evaluation can detect overflow here.
199 
200  bool __overflow = __builtin_mul_overflow(__r, __n2, &__r);
201  __glibcxx_assert(!__overflow);
202  return __r;
203  }
204 
205 #endif // C++17
206 #endif // C++14
207 
208 #if __cplusplus > 201703L
209 
210  // midpoint
211 # define __cpp_lib_interpolate 201902L
212 
213  template<typename _Tp>
214  constexpr
215  enable_if_t<__and_v<is_arithmetic<_Tp>, is_same<remove_cv_t<_Tp>, _Tp>,
216  __not_<is_same<_Tp, bool>>>,
217  _Tp>
218  midpoint(_Tp __a, _Tp __b) noexcept
219  {
220  if constexpr (is_integral_v<_Tp>)
221  {
222  using _Up = make_unsigned_t<_Tp>;
223 
224  int __k = 1;
225  _Up __m = __a;
226  _Up __M = __b;
227  if (__a > __b)
228  {
229  __k = -1;
230  __m = __b;
231  __M = __a;
232  }
233  return __a + __k * _Tp(_Up(__M - __m) / 2);
234  }
235  else // is_floating
236  {
237  constexpr _Tp __lo = numeric_limits<_Tp>::min() * 2;
238  constexpr _Tp __hi = numeric_limits<_Tp>::max() / 2;
239  const _Tp __abs_a = __a < 0 ? -__a : __a;
240  const _Tp __abs_b = __b < 0 ? -__b : __b;
241  if (__abs_a <= __hi && __abs_b <= __hi) [[likely]]
242  return (__a + __b) / 2; // always correctly rounded
243  if (__abs_a < __lo) // not safe to halve __a
244  return __a + __b/2;
245  if (__abs_b < __lo) // not safe to halve __b
246  return __a/2 + __b;
247  return __a/2 + __b/2; // otherwise correctly rounded
248  }
249  }
250 
251  template<typename _Tp>
252  constexpr enable_if_t<is_object_v<_Tp>, _Tp*>
253  midpoint(_Tp* __a, _Tp* __b) noexcept
254  {
255  static_assert( sizeof(_Tp) != 0, "type must be complete" );
256  return __a + (__b - __a) / 2;
257  }
258 #endif // C++20
259 
260 #if __cplusplus >= 201703L
261 
262 #if __cplusplus > 201703L
263 #define __cpp_lib_constexpr_numeric 201911L
264 #endif
265 
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 
747 // Feature test macro for parallel algorithms
748 # define __cpp_lib_parallel_algorithm 201603L
749 #endif // C++17
750 
751 #endif /* _GLIBCXX_NUMERIC */