Home | History | Annotate | Download | only in include
      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 
    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 
    155 template <class _InputIterator, class _Tp>
    156 inline _LIBCPP_INLINE_VISIBILITY
    157 _Tp
    158 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
    159 {
    160     for (; __first != __last; ++__first)
    161         __init = __init + *__first;
    162     return __init;
    163 }
    164 
    165 template <class _InputIterator, class _Tp, class _BinaryOperation>
    166 inline _LIBCPP_INLINE_VISIBILITY
    167 _Tp
    168 accumulate(_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
    176 template <class _InputIterator, class _Tp, class _BinaryOp>
    177 inline _LIBCPP_INLINE_VISIBILITY
    178 _Tp
    179 reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b)
    180 {
    181     for (; __first != __last; ++__first)
    182         __init = __b(__init, *__first);
    183     return __init;
    184 }
    185 
    186 template <class _InputIterator, class _Tp>
    187 inline _LIBCPP_INLINE_VISIBILITY
    188 _Tp
    189 reduce(_InputIterator __first, _InputIterator __last, _Tp __init)
    190 {
    191     return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>());
    192 }
    193 
    194 template <class _InputIterator>
    195 inline _LIBCPP_INLINE_VISIBILITY
    196 typename iterator_traits<_InputIterator>::value_type
    197 reduce(_InputIterator __first, _InputIterator __last)
    198 {
    199     return _VSTD::reduce(__first, __last,
    200        typename iterator_traits<_InputIterator>::value_type{});
    201 }
    202 #endif
    203 
    204 template <class _InputIterator1, class _InputIterator2, class _Tp>
    205 inline _LIBCPP_INLINE_VISIBILITY
    206 _Tp
    207 inner_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 
    214 template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
    215 inline _LIBCPP_INLINE_VISIBILITY
    216 _Tp
    217 inner_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
    226 template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
    227 inline _LIBCPP_INLINE_VISIBILITY
    228 _Tp
    229 transform_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 
    237 template <class _InputIterator1, class _InputIterator2,
    238           class _Tp, class _BinaryOp1, class _BinaryOp2>
    239 inline _LIBCPP_INLINE_VISIBILITY
    240 _Tp
    241 transform_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 
    249 template <class _InputIterator1, class _InputIterator2, class _Tp>
    250 inline _LIBCPP_INLINE_VISIBILITY
    251 _Tp
    252 transform_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 
    260 template <class _InputIterator, class _OutputIterator>
    261 inline _LIBCPP_INLINE_VISIBILITY
    262 _OutputIterator
    263 partial_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 
    278 template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
    279 inline _LIBCPP_INLINE_VISIBILITY
    280 _OutputIterator
    281 partial_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
    298 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
    299 inline _LIBCPP_INLINE_VISIBILITY
    300 _OutputIterator
    301 exclusive_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 
    318 template <class _InputIterator, class _OutputIterator, class _Tp>
    319 inline _LIBCPP_INLINE_VISIBILITY
    320 _OutputIterator
    321 exclusive_scan(_InputIterator __first, _InputIterator __last,
    322                _OutputIterator __result, _Tp __init)
    323 {
    324     return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>());
    325 }
    326 
    327 template <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 
    338 template <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 
    352 template <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 
    359 template <class _InputIterator, class _OutputIterator, class _Tp,
    360           class _BinaryOp, class _UnaryOp>
    361 inline _LIBCPP_INLINE_VISIBILITY
    362 _OutputIterator
    363 transform_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 
    381 template <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 
    393 template <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 
    408 template <class _InputIterator, class _OutputIterator>
    409 inline _LIBCPP_INLINE_VISIBILITY
    410 _OutputIterator
    411 adjacent_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 
    427 template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
    428 inline _LIBCPP_INLINE_VISIBILITY
    429 _OutputIterator
    430 adjacent_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 
    447 template <class _ForwardIterator, class _Tp>
    448 inline _LIBCPP_INLINE_VISIBILITY
    449 void
    450 iota(_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
    458 template <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __abs;
    459 
    460 template <typename _Result, typename _Source>
    461 struct __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 
    471 template <typename _Result, typename _Source>
    472 struct __abs<_Result, _Source, false> {
    473     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    474     _Result operator()(_Source __t) const noexcept { return __t; }
    475 };
    476 
    477 
    478 template<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 
    487 template<class _Tp, class _Up>
    488 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    489 common_type_t<_Tp,_Up>
    490 gcd(_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 
    502 template<class _Tp, class _Up>
    503 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    504 common_type_t<_Tp,_Up>
    505 lcm(_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