1 // -*- C++ -*- 2 //===---------------------------- numeric ---------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef _LIBCPP_NUMERIC 12 #define _LIBCPP_NUMERIC 13 14 /* 15 numeric synopsis 16 17 namespace std 18 { 19 20 template <class InputIterator, class T> 21 T 22 accumulate(InputIterator first, InputIterator last, T init); 23 24 template <class InputIterator, class T, class BinaryOperation> 25 T 26 accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); 27 28 template<class InputIterator> 29 typename iterator_traits<InputIterator>::value_type 30 reduce(InputIterator first, InputIterator last); // C++17 31 32 template<class InputIterator, class T> 33 T 34 reduce(InputIterator first, InputIterator last, T init); // C++17 35 36 template<class InputIterator, class T, class BinaryOperation> 37 T 38 reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); // C++17 39 40 template <class InputIterator1, class InputIterator2, class T> 41 T 42 inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); 43 44 template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2> 45 T 46 inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, 47 T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); 48 49 50 template<class InputIterator1, class InputIterator2, class T> 51 T 52 transform_reduce(InputIterator1 first1, InputIterator1 last1, 53 InputIterator2 first2, T init); // C++17 54 55 template<class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2> 56 T 57 transform_reduce(InputIterator1 first1, InputIterator1 last1, 58 InputIterator2 first2, T init, 59 BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); // C++17 60 61 template<class InputIterator, class T, class BinaryOperation, class UnaryOperation> 62 T 63 transform_reduce(InputIterator first, InputIterator last, T init, 64 BinaryOperation binary_op, UnaryOperation unary_op); // C++17 65 66 template <class InputIterator, class OutputIterator> 67 OutputIterator 68 partial_sum(InputIterator first, InputIterator last, OutputIterator result); 69 70 template <class InputIterator, class OutputIterator, class BinaryOperation> 71 OutputIterator 72 partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); 73 74 template<class InputIterator, class OutputIterator, class T> 75 OutputIterator 76 exclusive_scan(InputIterator first, InputIterator last, 77 OutputIterator result, T init); // C++17 78 79 template<class InputIterator, class OutputIterator, class T, class BinaryOperation> 80 OutputIterator 81 exclusive_scan(InputIterator first, InputIterator last, 82 OutputIterator result, T init, BinaryOperation binary_op); // C++17 83 84 template<class InputIterator, class OutputIterator> 85 OutputIterator 86 inclusive_scan(InputIterator first, InputIterator last, OutputIterator result); // C++17 87 88 template<class InputIterator, class OutputIterator, class BinaryOperation> 89 OutputIterator 90 inclusive_scan(InputIterator first, InputIterator last, 91 OutputIterator result, BinaryOperation binary_op); // C++17 92 93 template<class InputIterator, class OutputIterator, class BinaryOperation, class T> 94 OutputIterator 95 inclusive_scan(InputIterator first, InputIterator last, 96 OutputIterator result, BinaryOperation binary_op, T init); // C++17 97 98 template<class InputIterator, class OutputIterator, class T, 99 class BinaryOperation, class UnaryOperation> 100 OutputIterator 101 transform_exclusive_scan(InputIterator first, InputIterator last, 102 OutputIterator result, T init, 103 BinaryOperation binary_op, UnaryOperation unary_op); // C++17 104 105 template<class InputIterator, class OutputIterator, 106 class BinaryOperation, class UnaryOperation> 107 OutputIterator 108 transform_inclusive_scan(InputIterator first, InputIterator last, 109 OutputIterator result, 110 BinaryOperation binary_op, UnaryOperation unary_op); // C++17 111 112 template<class InputIterator, class OutputIterator, 113 class BinaryOperation, class UnaryOperation, class T> 114 OutputIterator 115 transform_inclusive_scan(InputIterator first, InputIterator last, 116 OutputIterator result, 117 BinaryOperation binary_op, UnaryOperation unary_op, 118 T init); // C++17 119 120 template <class InputIterator, class OutputIterator> 121 OutputIterator 122 adjacent_difference(InputIterator first, InputIterator last, OutputIterator result); 123 124 template <class InputIterator, class OutputIterator, class BinaryOperation> 125 OutputIterator 126 adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); 127 128 template <class ForwardIterator, class T> 129 void iota(ForwardIterator first, ForwardIterator last, T value); 130 131 template <class M, class N> 132 constexpr common_type_t<M,N> gcd(M m, N n); // C++17 133 134 template <class M, class N> 135 constexpr common_type_t<M,N> lcm(M m, N n); // C++17 136 137 } // std 138 139 */ 140 141 #include <__config> 142 #include <iterator> 143 #include <limits> // for numeric_limits 144 #include <functional> 145 #include <version> 146 147 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 148 #pragma GCC system_header 149 #endif 150 151 _LIBCPP_PUSH_MACROS 152 #include <__undef_macros> 153 154 _LIBCPP_BEGIN_NAMESPACE_STD 155 156 template <class _InputIterator, class _Tp> 157 inline _LIBCPP_INLINE_VISIBILITY 158 _Tp 159 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) 160 { 161 for (; __first != __last; ++__first) 162 __init = __init + *__first; 163 return __init; 164 } 165 166 template <class _InputIterator, class _Tp, class _BinaryOperation> 167 inline _LIBCPP_INLINE_VISIBILITY 168 _Tp 169 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) 170 { 171 for (; __first != __last; ++__first) 172 __init = __binary_op(__init, *__first); 173 return __init; 174 } 175 176 #if _LIBCPP_STD_VER > 14 177 template <class _InputIterator, class _Tp, class _BinaryOp> 178 inline _LIBCPP_INLINE_VISIBILITY 179 _Tp 180 reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b) 181 { 182 for (; __first != __last; ++__first) 183 __init = __b(__init, *__first); 184 return __init; 185 } 186 187 template <class _InputIterator, class _Tp> 188 inline _LIBCPP_INLINE_VISIBILITY 189 _Tp 190 reduce(_InputIterator __first, _InputIterator __last, _Tp __init) 191 { 192 return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>()); 193 } 194 195 template <class _InputIterator> 196 inline _LIBCPP_INLINE_VISIBILITY 197 typename iterator_traits<_InputIterator>::value_type 198 reduce(_InputIterator __first, _InputIterator __last) 199 { 200 return _VSTD::reduce(__first, __last, 201 typename iterator_traits<_InputIterator>::value_type{}); 202 } 203 #endif 204 205 template <class _InputIterator1, class _InputIterator2, class _Tp> 206 inline _LIBCPP_INLINE_VISIBILITY 207 _Tp 208 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) 209 { 210 for (; __first1 != __last1; ++__first1, (void) ++__first2) 211 __init = __init + *__first1 * *__first2; 212 return __init; 213 } 214 215 template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2> 216 inline _LIBCPP_INLINE_VISIBILITY 217 _Tp 218 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, 219 _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) 220 { 221 for (; __first1 != __last1; ++__first1, (void) ++__first2) 222 __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); 223 return __init; 224 } 225 226 #if _LIBCPP_STD_VER > 14 227 template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp> 228 inline _LIBCPP_INLINE_VISIBILITY 229 _Tp 230 transform_reduce(_InputIterator __first, _InputIterator __last, 231 _Tp __init, _BinaryOp __b, _UnaryOp __u) 232 { 233 for (; __first != __last; ++__first) 234 __init = __b(__init, __u(*__first)); 235 return __init; 236 } 237 238 template <class _InputIterator1, class _InputIterator2, 239 class _Tp, class _BinaryOp1, class _BinaryOp2> 240 inline _LIBCPP_INLINE_VISIBILITY 241 _Tp 242 transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, 243 _InputIterator2 __first2, _Tp __init, _BinaryOp1 __b1, _BinaryOp2 __b2) 244 { 245 for (; __first1 != __last1; ++__first1, (void) ++__first2) 246 __init = __b1(__init, __b2(*__first1, *__first2)); 247 return __init; 248 } 249 250 template <class _InputIterator1, class _InputIterator2, class _Tp> 251 inline _LIBCPP_INLINE_VISIBILITY 252 _Tp 253 transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, 254 _InputIterator2 __first2, _Tp __init) 255 { 256 return _VSTD::transform_reduce(__first1, __last1, __first2, _VSTD::move(__init), 257 _VSTD::plus<>(), _VSTD::multiplies<>()); 258 } 259 #endif 260 261 template <class _InputIterator, class _OutputIterator> 262 inline _LIBCPP_INLINE_VISIBILITY 263 _OutputIterator 264 partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 265 { 266 if (__first != __last) 267 { 268 typename iterator_traits<_InputIterator>::value_type __t(*__first); 269 *__result = __t; 270 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) 271 { 272 __t = __t + *__first; 273 *__result = __t; 274 } 275 } 276 return __result; 277 } 278 279 template <class _InputIterator, class _OutputIterator, class _BinaryOperation> 280 inline _LIBCPP_INLINE_VISIBILITY 281 _OutputIterator 282 partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 283 _BinaryOperation __binary_op) 284 { 285 if (__first != __last) 286 { 287 typename iterator_traits<_InputIterator>::value_type __t(*__first); 288 *__result = __t; 289 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) 290 { 291 __t = __binary_op(__t, *__first); 292 *__result = __t; 293 } 294 } 295 return __result; 296 } 297 298 #if _LIBCPP_STD_VER > 14 299 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp> 300 inline _LIBCPP_INLINE_VISIBILITY 301 _OutputIterator 302 exclusive_scan(_InputIterator __first, _InputIterator __last, 303 _OutputIterator __result, _Tp __init, _BinaryOp __b) 304 { 305 if (__first != __last) 306 { 307 _Tp __saved = __init; 308 do 309 { 310 __init = __b(__init, *__first); 311 *__result = __saved; 312 __saved = __init; 313 ++__result; 314 } while (++__first != __last); 315 } 316 return __result; 317 } 318 319 template <class _InputIterator, class _OutputIterator, class _Tp> 320 inline _LIBCPP_INLINE_VISIBILITY 321 _OutputIterator 322 exclusive_scan(_InputIterator __first, _InputIterator __last, 323 _OutputIterator __result, _Tp __init) 324 { 325 return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>()); 326 } 327 328 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp> 329 _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, 330 _OutputIterator __result, _BinaryOp __b, _Tp __init) 331 { 332 for (; __first != __last; ++__first, (void) ++__result) { 333 __init = __b(__init, *__first); 334 *__result = __init; 335 } 336 return __result; 337 } 338 339 template <class _InputIterator, class _OutputIterator, class _BinaryOp> 340 _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, 341 _OutputIterator __result, _BinaryOp __b) 342 { 343 if (__first != __last) { 344 typename std::iterator_traits<_InputIterator>::value_type __init = *__first; 345 *__result++ = __init; 346 if (++__first != __last) 347 return _VSTD::inclusive_scan(__first, __last, __result, __b, __init); 348 } 349 350 return __result; 351 } 352 353 template <class _InputIterator, class _OutputIterator> 354 _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, 355 _OutputIterator __result) 356 { 357 return _VSTD::inclusive_scan(__first, __last, __result, std::plus<>()); 358 } 359 360 template <class _InputIterator, class _OutputIterator, class _Tp, 361 class _BinaryOp, class _UnaryOp> 362 inline _LIBCPP_INLINE_VISIBILITY 363 _OutputIterator 364 transform_exclusive_scan(_InputIterator __first, _InputIterator __last, 365 _OutputIterator __result, _Tp __init, 366 _BinaryOp __b, _UnaryOp __u) 367 { 368 if (__first != __last) 369 { 370 _Tp __saved = __init; 371 do 372 { 373 __init = __b(__init, __u(*__first)); 374 *__result = __saved; 375 __saved = __init; 376 ++__result; 377 } while (++__first != __last); 378 } 379 return __result; 380 } 381 382 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp> 383 _OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last, 384 _OutputIterator __result, _BinaryOp __b, _UnaryOp __u, _Tp __init) 385 { 386 for (; __first != __last; ++__first, (void) ++__result) { 387 __init = __b(__init, __u(*__first)); 388 *__result = __init; 389 } 390 391 return __result; 392 } 393 394 template <class _InputIterator, class _OutputIterator, class _BinaryOp, class _UnaryOp> 395 _OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last, 396 _OutputIterator __result, _BinaryOp __b, _UnaryOp __u) 397 { 398 if (__first != __last) { 399 typename std::iterator_traits<_InputIterator>::value_type __init = __u(*__first); 400 *__result++ = __init; 401 if (++__first != __last) 402 return _VSTD::transform_inclusive_scan(__first, __last, __result, __b, __u, __init); 403 } 404 405 return __result; 406 } 407 #endif 408 409 template <class _InputIterator, class _OutputIterator> 410 inline _LIBCPP_INLINE_VISIBILITY 411 _OutputIterator 412 adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 413 { 414 if (__first != __last) 415 { 416 typename iterator_traits<_InputIterator>::value_type __t1(*__first); 417 *__result = __t1; 418 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) 419 { 420 typename iterator_traits<_InputIterator>::value_type __t2(*__first); 421 *__result = __t2 - __t1; 422 __t1 = _VSTD::move(__t2); 423 } 424 } 425 return __result; 426 } 427 428 template <class _InputIterator, class _OutputIterator, class _BinaryOperation> 429 inline _LIBCPP_INLINE_VISIBILITY 430 _OutputIterator 431 adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 432 _BinaryOperation __binary_op) 433 { 434 if (__first != __last) 435 { 436 typename iterator_traits<_InputIterator>::value_type __t1(*__first); 437 *__result = __t1; 438 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) 439 { 440 typename iterator_traits<_InputIterator>::value_type __t2(*__first); 441 *__result = __binary_op(__t2, __t1); 442 __t1 = _VSTD::move(__t2); 443 } 444 } 445 return __result; 446 } 447 448 template <class _ForwardIterator, class _Tp> 449 inline _LIBCPP_INLINE_VISIBILITY 450 void 451 iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_) 452 { 453 for (; __first != __last; ++__first, (void) ++__value_) 454 *__first = __value_; 455 } 456 457 458 #if _LIBCPP_STD_VER > 14 459 template <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __abs; 460 461 template <typename _Result, typename _Source> 462 struct __abs<_Result, _Source, true> { 463 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 464 _Result operator()(_Source __t) const noexcept 465 { 466 if (__t >= 0) return __t; 467 if (__t == numeric_limits<_Source>::min()) return -static_cast<_Result>(__t); 468 return -__t; 469 } 470 }; 471 472 template <typename _Result, typename _Source> 473 struct __abs<_Result, _Source, false> { 474 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 475 _Result operator()(_Source __t) const noexcept { return __t; } 476 }; 477 478 479 template<class _Tp> 480 _LIBCPP_CONSTEXPR _LIBCPP_HIDDEN 481 _Tp __gcd(_Tp __m, _Tp __n) 482 { 483 static_assert((!is_signed<_Tp>::value), ""); 484 return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n); 485 } 486 487 488 template<class _Tp, class _Up> 489 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 490 common_type_t<_Tp,_Up> 491 gcd(_Tp __m, _Up __n) 492 { 493 static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types"); 494 static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to gcd cannot be bool" ); 495 static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to gcd cannot be bool" ); 496 using _Rp = common_type_t<_Tp,_Up>; 497 using _Wp = make_unsigned_t<_Rp>; 498 return static_cast<_Rp>(_VSTD::__gcd( 499 static_cast<_Wp>(__abs<_Rp, _Tp>()(__m)), 500 static_cast<_Wp>(__abs<_Rp, _Up>()(__n)))); 501 } 502 503 template<class _Tp, class _Up> 504 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 505 common_type_t<_Tp,_Up> 506 lcm(_Tp __m, _Up __n) 507 { 508 static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types"); 509 static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to lcm cannot be bool" ); 510 static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to lcm cannot be bool" ); 511 if (__m == 0 || __n == 0) 512 return 0; 513 514 using _Rp = common_type_t<_Tp,_Up>; 515 _Rp __val1 = __abs<_Rp, _Tp>()(__m) / _VSTD::gcd(__m, __n); 516 _Rp __val2 = __abs<_Rp, _Up>()(__n); 517 _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); 518 return __val1 * __val2; 519 } 520 521 #endif /* _LIBCPP_STD_VER > 14 */ 522 523 _LIBCPP_END_NAMESPACE_STD 524 525 _LIBCPP_POP_MACROS 526 527 #endif // _LIBCPP_NUMERIC 528