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