13e519524SHoward Hinnant// -*- C++ -*- 23e519524SHoward Hinnant//===---------------------------- numeric ---------------------------------===// 33e519524SHoward Hinnant// 45b08a8a4SHoward Hinnant// The LLVM Compiler Infrastructure 53e519524SHoward Hinnant// 6412dbebeSHoward Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 7412dbebeSHoward Hinnant// Source Licenses. See LICENSE.TXT for details. 83e519524SHoward Hinnant// 93e519524SHoward Hinnant//===----------------------------------------------------------------------===// 103e519524SHoward Hinnant 113e519524SHoward Hinnant#ifndef _LIBCPP_NUMERIC 123e519524SHoward Hinnant#define _LIBCPP_NUMERIC 133e519524SHoward Hinnant 143e519524SHoward Hinnant/* 153e519524SHoward Hinnant numeric synopsis 163e519524SHoward Hinnant 173e519524SHoward Hinnantnamespace std 183e519524SHoward Hinnant{ 193e519524SHoward Hinnant 203e519524SHoward Hinnanttemplate <class InputIterator, class T> 213e519524SHoward Hinnant T 223e519524SHoward Hinnant accumulate(InputIterator first, InputIterator last, T init); 233e519524SHoward Hinnant 243e519524SHoward Hinnanttemplate <class InputIterator, class T, class BinaryOperation> 253e519524SHoward Hinnant T 263e519524SHoward Hinnant accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); 273e519524SHoward Hinnant 283e519524SHoward Hinnanttemplate <class InputIterator1, class InputIterator2, class T> 293e519524SHoward Hinnant T 303e519524SHoward Hinnant inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); 313e519524SHoward Hinnant 323e519524SHoward Hinnanttemplate <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2> 333e519524SHoward Hinnant T 343e519524SHoward Hinnant inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, 353e519524SHoward Hinnant T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); 363e519524SHoward Hinnant 373e519524SHoward Hinnanttemplate <class InputIterator, class OutputIterator> 383e519524SHoward Hinnant OutputIterator 393e519524SHoward Hinnant partial_sum(InputIterator first, InputIterator last, OutputIterator result); 403e519524SHoward Hinnant 413e519524SHoward Hinnanttemplate <class InputIterator, class OutputIterator, class BinaryOperation> 423e519524SHoward Hinnant OutputIterator 433e519524SHoward Hinnant partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); 443e519524SHoward Hinnant 453e519524SHoward Hinnanttemplate <class InputIterator, class OutputIterator> 463e519524SHoward Hinnant OutputIterator 473e519524SHoward Hinnant adjacent_difference(InputIterator first, InputIterator last, OutputIterator result); 483e519524SHoward Hinnant 493e519524SHoward Hinnanttemplate <class InputIterator, class OutputIterator, class BinaryOperation> 503e519524SHoward Hinnant OutputIterator 513e519524SHoward Hinnant adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); 523e519524SHoward Hinnant 5340c7ef90SHoward Hinnanttemplate <class ForwardIterator, class T> 5440c7ef90SHoward Hinnant void iota(ForwardIterator first, ForwardIterator last, T value); 5540c7ef90SHoward Hinnant 5619b4035fSMarshall Clowtemplate <class M, class N> 5719b4035fSMarshall Clow constexpr common_type_t<M,N> gcd(M m, N n); // C++17 5819b4035fSMarshall Clow 5919b4035fSMarshall Clowtemplate <class M, class N> 6019b4035fSMarshall Clow constexpr common_type_t<M,N> lcm(M m, N n); // C++17 6119b4035fSMarshall Clow 623e519524SHoward Hinnant} // std 633e519524SHoward Hinnant 643e519524SHoward Hinnant*/ 653e519524SHoward Hinnant 663e519524SHoward Hinnant#include <__config> 673e519524SHoward Hinnant#include <iterator> 68d35528b3SEric Fiselier#include <limits> // for numeric_limits 693e519524SHoward Hinnant 70073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 713e519524SHoward Hinnant#pragma GCC system_header 72073458b1SHoward Hinnant#endif 733e519524SHoward Hinnant 743e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 753e519524SHoward Hinnant 763e519524SHoward Hinnanttemplate <class _InputIterator, class _Tp> 773e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 783e519524SHoward Hinnant_Tp 793e519524SHoward Hinnantaccumulate(_InputIterator __first, _InputIterator __last, _Tp __init) 803e519524SHoward Hinnant{ 813e519524SHoward Hinnant for (; __first != __last; ++__first) 823e519524SHoward Hinnant __init = __init + *__first; 833e519524SHoward Hinnant return __init; 843e519524SHoward Hinnant} 853e519524SHoward Hinnant 863e519524SHoward Hinnanttemplate <class _InputIterator, class _Tp, class _BinaryOperation> 873e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 883e519524SHoward Hinnant_Tp 893e519524SHoward Hinnantaccumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) 903e519524SHoward Hinnant{ 913e519524SHoward Hinnant for (; __first != __last; ++__first) 923e519524SHoward Hinnant __init = __binary_op(__init, *__first); 933e519524SHoward Hinnant return __init; 943e519524SHoward Hinnant} 953e519524SHoward Hinnant 963e519524SHoward Hinnanttemplate <class _InputIterator1, class _InputIterator2, class _Tp> 973e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 983e519524SHoward Hinnant_Tp 993e519524SHoward Hinnantinner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) 1003e519524SHoward Hinnant{ 101910285b2SEric Fiselier for (; __first1 != __last1; ++__first1, (void) ++__first2) 1023e519524SHoward Hinnant __init = __init + *__first1 * *__first2; 1033e519524SHoward Hinnant return __init; 1043e519524SHoward Hinnant} 1053e519524SHoward Hinnant 1063e519524SHoward Hinnanttemplate <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2> 1073e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1083e519524SHoward Hinnant_Tp 1093e519524SHoward Hinnantinner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, 1103e519524SHoward Hinnant _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) 1113e519524SHoward Hinnant{ 112910285b2SEric Fiselier for (; __first1 != __last1; ++__first1, (void) ++__first2) 1133e519524SHoward Hinnant __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); 1143e519524SHoward Hinnant return __init; 1153e519524SHoward Hinnant} 1163e519524SHoward Hinnant 1173e519524SHoward Hinnanttemplate <class _InputIterator, class _OutputIterator> 1183e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1193e519524SHoward Hinnant_OutputIterator 1203e519524SHoward Hinnantpartial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1213e519524SHoward Hinnant{ 1223e519524SHoward Hinnant if (__first != __last) 1233e519524SHoward Hinnant { 1243e519524SHoward Hinnant typename iterator_traits<_InputIterator>::value_type __t(*__first); 1253e519524SHoward Hinnant *__result = __t; 126910285b2SEric Fiselier for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) 1273e519524SHoward Hinnant { 1283e519524SHoward Hinnant __t = __t + *__first; 1293e519524SHoward Hinnant *__result = __t; 1303e519524SHoward Hinnant } 1313e519524SHoward Hinnant } 1323e519524SHoward Hinnant return __result; 1333e519524SHoward Hinnant} 1343e519524SHoward Hinnant 1353e519524SHoward Hinnanttemplate <class _InputIterator, class _OutputIterator, class _BinaryOperation> 1363e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1373e519524SHoward Hinnant_OutputIterator 1383e519524SHoward Hinnantpartial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 1393e519524SHoward Hinnant _BinaryOperation __binary_op) 1403e519524SHoward Hinnant{ 1413e519524SHoward Hinnant if (__first != __last) 1423e519524SHoward Hinnant { 1433e519524SHoward Hinnant typename iterator_traits<_InputIterator>::value_type __t(*__first); 1443e519524SHoward Hinnant *__result = __t; 145910285b2SEric Fiselier for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) 1463e519524SHoward Hinnant { 1473e519524SHoward Hinnant __t = __binary_op(__t, *__first); 1483e519524SHoward Hinnant *__result = __t; 1493e519524SHoward Hinnant } 1503e519524SHoward Hinnant } 1513e519524SHoward Hinnant return __result; 1523e519524SHoward Hinnant} 1533e519524SHoward Hinnant 1543e519524SHoward Hinnanttemplate <class _InputIterator, class _OutputIterator> 1553e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1563e519524SHoward Hinnant_OutputIterator 1573e519524SHoward Hinnantadjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 1583e519524SHoward Hinnant{ 1593e519524SHoward Hinnant if (__first != __last) 1603e519524SHoward Hinnant { 1613e519524SHoward Hinnant typename iterator_traits<_InputIterator>::value_type __t1(*__first); 1623e519524SHoward Hinnant *__result = __t1; 163910285b2SEric Fiselier for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) 1643e519524SHoward Hinnant { 1653e519524SHoward Hinnant typename iterator_traits<_InputIterator>::value_type __t2(*__first); 1663e519524SHoward Hinnant *__result = __t2 - __t1; 1679ff3203fSHoward Hinnant __t1 = _VSTD::move(__t2); 1683e519524SHoward Hinnant } 1693e519524SHoward Hinnant } 1703e519524SHoward Hinnant return __result; 1713e519524SHoward Hinnant} 1723e519524SHoward Hinnant 1733e519524SHoward Hinnanttemplate <class _InputIterator, class _OutputIterator, class _BinaryOperation> 1743e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1753e519524SHoward Hinnant_OutputIterator 1763e519524SHoward Hinnantadjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, 1773e519524SHoward Hinnant _BinaryOperation __binary_op) 1783e519524SHoward Hinnant{ 1793e519524SHoward Hinnant if (__first != __last) 1803e519524SHoward Hinnant { 1813e519524SHoward Hinnant typename iterator_traits<_InputIterator>::value_type __t1(*__first); 1823e519524SHoward Hinnant *__result = __t1; 183910285b2SEric Fiselier for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) 1843e519524SHoward Hinnant { 1853e519524SHoward Hinnant typename iterator_traits<_InputIterator>::value_type __t2(*__first); 1863e519524SHoward Hinnant *__result = __binary_op(__t2, __t1); 1879ff3203fSHoward Hinnant __t1 = _VSTD::move(__t2); 1883e519524SHoward Hinnant } 1893e519524SHoward Hinnant } 1903e519524SHoward Hinnant return __result; 1913e519524SHoward Hinnant} 1923e519524SHoward Hinnant 19340c7ef90SHoward Hinnanttemplate <class _ForwardIterator, class _Tp> 19440c7ef90SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 19540c7ef90SHoward Hinnantvoid 196e4383379SHoward Hinnantiota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_) 19740c7ef90SHoward Hinnant{ 198910285b2SEric Fiselier for (; __first != __last; ++__first, (void) ++__value_) 199e4383379SHoward Hinnant *__first = __value_; 20040c7ef90SHoward Hinnant} 20140c7ef90SHoward Hinnant 20219b4035fSMarshall Clow 20319b4035fSMarshall Clow#if _LIBCPP_STD_VER > 14 20458fc1b50SMarshall Clowtemplate <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __abs; 20519b4035fSMarshall Clow 20658fc1b50SMarshall Clowtemplate <typename _Result, typename _Source> 20758fc1b50SMarshall Clowstruct __abs<_Result, _Source, true> { 20819b4035fSMarshall Clow _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 20958fc1b50SMarshall Clow _Result operator()(_Source __t) const noexcept 21058fc1b50SMarshall Clow { 21158fc1b50SMarshall Clow if (__t >= 0) return __t; 21258fc1b50SMarshall Clow if (__t == numeric_limits<_Source>::min()) return -static_cast<_Result>(__t); 21358fc1b50SMarshall Clow return -__t; 21458fc1b50SMarshall Clow } 21519b4035fSMarshall Clow}; 21619b4035fSMarshall Clow 21758fc1b50SMarshall Clowtemplate <typename _Result, typename _Source> 21858fc1b50SMarshall Clowstruct __abs<_Result, _Source, false> { 21919b4035fSMarshall Clow _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 22058fc1b50SMarshall Clow _Result operator()(_Source __t) const noexcept { return __t; } 22119b4035fSMarshall Clow}; 22219b4035fSMarshall Clow 22319b4035fSMarshall Clow 22419b4035fSMarshall Clowtemplate<class _Tp> 225*50d61da2SEric Fiselier_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN 22619b4035fSMarshall Clow_Tp __gcd(_Tp __m, _Tp __n) 22719b4035fSMarshall Clow{ 22819b4035fSMarshall Clow static_assert((!is_signed<_Tp>::value), ""); 229*50d61da2SEric Fiselier return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n); 23019b4035fSMarshall Clow} 23119b4035fSMarshall Clow 23219b4035fSMarshall Clow 23319b4035fSMarshall Clowtemplate<class _Tp, class _Up> 23419b4035fSMarshall Clow_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 23519b4035fSMarshall Clowcommon_type_t<_Tp,_Up> 23619b4035fSMarshall Clowgcd(_Tp __m, _Up __n) 23719b4035fSMarshall Clow{ 23819b4035fSMarshall Clow static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types"); 2391c7fe126SMarshall Clow static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to gcd cannot be bool" ); 2401c7fe126SMarshall Clow static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to gcd cannot be bool" ); 24119b4035fSMarshall Clow using _Rp = common_type_t<_Tp,_Up>; 24219b4035fSMarshall Clow using _Wp = make_unsigned_t<_Rp>; 243*50d61da2SEric Fiselier return static_cast<_Rp>(_VSTD::__gcd( 244*50d61da2SEric Fiselier static_cast<_Wp>(__abs<_Rp, _Tp>()(__m)), 24558fc1b50SMarshall Clow static_cast<_Wp>(__abs<_Rp, _Up>()(__n)))); 24619b4035fSMarshall Clow} 24719b4035fSMarshall Clow 24819b4035fSMarshall Clowtemplate<class _Tp, class _Up> 24919b4035fSMarshall Clow_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY 25019b4035fSMarshall Clowcommon_type_t<_Tp,_Up> 25119b4035fSMarshall Clowlcm(_Tp __m, _Up __n) 25219b4035fSMarshall Clow{ 25319b4035fSMarshall Clow static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types"); 2541c7fe126SMarshall Clow static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to lcm cannot be bool" ); 2551c7fe126SMarshall Clow static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to lcm cannot be bool" ); 25619b4035fSMarshall Clow if (__m == 0 || __n == 0) 25719b4035fSMarshall Clow return 0; 25819b4035fSMarshall Clow 25919b4035fSMarshall Clow using _Rp = common_type_t<_Tp,_Up>; 260*50d61da2SEric Fiselier _Rp __val1 = __abs<_Rp, _Tp>()(__m) / _VSTD::gcd(__m, __n); 26158fc1b50SMarshall Clow _Rp __val2 = __abs<_Rp, _Up>()(__n); 26219b4035fSMarshall Clow _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); 26319b4035fSMarshall Clow return __val1 * __val2; 26419b4035fSMarshall Clow} 26519b4035fSMarshall Clow 26619b4035fSMarshall Clow#endif /* _LIBCPP_STD_VER > 14 */ 26719b4035fSMarshall Clow 2683e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD 2693e519524SHoward Hinnant 2703e519524SHoward Hinnant#endif // _LIBCPP_NUMERIC 271