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