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