2 //===---------------------------- numeric ---------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_NUMERIC
12 #define _LIBCPP_NUMERIC
20 template <class InputIterator, class T>
22 accumulate(InputIterator first, InputIterator last, T init);
24 template <class InputIterator, class T, class BinaryOperation>
26 accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
28 template<class InputIterator>
29 typename iterator_traits<InputIterator>::value_type
30 reduce(InputIterator first, InputIterator last); // C++17
32 template<class InputIterator, class T>
34 reduce(InputIterator first, InputIterator last, T init); // C++17
36 template<class InputIterator, class T, class BinaryOperation>
38 reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); // C++17
40 template <class InputIterator1, class InputIterator2, class T>
42 inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);
44 template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
46 inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
47 T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
50 template<class InputIterator1, class InputIterator2, class T>
52 transform_reduce(InputIterator1 first1, InputIterator1 last1,
53 InputIterator2 first2, T init); // C++17
55 template<class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
57 transform_reduce(InputIterator1 first1, InputIterator1 last1,
58 InputIterator2 first2, T init,
59 BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); // C++17
61 template<class InputIterator, class T, class BinaryOperation, class UnaryOperation>
63 transform_reduce(InputIterator first, InputIterator last, T init,
64 BinaryOperation binary_op, UnaryOperation unary_op); // C++17
66 template <class InputIterator, class OutputIterator>
68 partial_sum(InputIterator first, InputIterator last, OutputIterator result);
70 template <class InputIterator, class OutputIterator, class BinaryOperation>
72 partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
74 template<class InputIterator, class OutputIterator, class T>
76 exclusive_scan(InputIterator first, InputIterator last,
77 OutputIterator result, T init); // C++17
79 template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
81 exclusive_scan(InputIterator first, InputIterator last,
82 OutputIterator result, T init, BinaryOperation binary_op); // C++17
84 template<class InputIterator, class OutputIterator>
86 inclusive_scan(InputIterator first, InputIterator last, OutputIterator result); // C++17
88 template<class InputIterator, class OutputIterator, class BinaryOperation>
90 inclusive_scan(InputIterator first, InputIterator last,
91 OutputIterator result, BinaryOperation binary_op); // C++17
93 template<class InputIterator, class OutputIterator, class BinaryOperation, class T>
95 inclusive_scan(InputIterator first, InputIterator last,
96 OutputIterator result, BinaryOperation binary_op, T init); // C++17
98 template<class InputIterator, class OutputIterator, class T,
99 class BinaryOperation, class UnaryOperation>
101 transform_exclusive_scan(InputIterator first, InputIterator last,
102 OutputIterator result, T init,
103 BinaryOperation binary_op, UnaryOperation unary_op); // C++17
105 template<class InputIterator, class OutputIterator,
106 class BinaryOperation, class UnaryOperation>
108 transform_inclusive_scan(InputIterator first, InputIterator last,
109 OutputIterator result,
110 BinaryOperation binary_op, UnaryOperation unary_op); // C++17
112 template<class InputIterator, class OutputIterator,
113 class BinaryOperation, class UnaryOperation, class T>
115 transform_inclusive_scan(InputIterator first, InputIterator last,
116 OutputIterator result,
117 BinaryOperation binary_op, UnaryOperation unary_op,
120 template <class InputIterator, class OutputIterator>
122 adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);
124 template <class InputIterator, class OutputIterator, class BinaryOperation>
126 adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
128 template <class ForwardIterator, class T>
129 void iota(ForwardIterator first, ForwardIterator last, T value);
131 template <class M, class N>
132 constexpr common_type_t<M,N> gcd(M m, N n); // C++17
134 template <class M, class N>
135 constexpr common_type_t<M,N> lcm(M m, N n); // C++17
143 #include <limits> // for numeric_limits
144 #include <functional>
146 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
147 #pragma GCC system_header
151 #include <__undef_macros>
153 _LIBCPP_BEGIN_NAMESPACE_STD
155 template <class _InputIterator, class _Tp>
156 inline _LIBCPP_INLINE_VISIBILITY
158 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
160 for (; __first != __last; ++__first)
161 __init = __init + *__first;
165 template <class _InputIterator, class _Tp, class _BinaryOperation>
166 inline _LIBCPP_INLINE_VISIBILITY
168 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
170 for (; __first != __last; ++__first)
171 __init = __binary_op(__init, *__first);
175 #if _LIBCPP_STD_VER > 14
176 template <class _InputIterator, class _Tp, class _BinaryOp>
177 inline _LIBCPP_INLINE_VISIBILITY
179 reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b)
181 for (; __first != __last; ++__first)
182 __init = __b(__init, *__first);
186 template <class _InputIterator, class _Tp>
187 inline _LIBCPP_INLINE_VISIBILITY
189 reduce(_InputIterator __first, _InputIterator __last, _Tp __init)
191 return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>());
194 template <class _InputIterator>
195 inline _LIBCPP_INLINE_VISIBILITY
196 typename iterator_traits<_InputIterator>::value_type
197 reduce(_InputIterator __first, _InputIterator __last)
199 return _VSTD::reduce(__first, __last,
200 typename iterator_traits<_InputIterator>::value_type{});
204 template <class _InputIterator1, class _InputIterator2, class _Tp>
205 inline _LIBCPP_INLINE_VISIBILITY
207 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
209 for (; __first1 != __last1; ++__first1, (void) ++__first2)
210 __init = __init + *__first1 * *__first2;
214 template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
215 inline _LIBCPP_INLINE_VISIBILITY
217 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
218 _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
220 for (; __first1 != __last1; ++__first1, (void) ++__first2)
221 __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
225 #if _LIBCPP_STD_VER > 14
226 template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
227 inline _LIBCPP_INLINE_VISIBILITY
229 transform_reduce(_InputIterator __first, _InputIterator __last,
230 _Tp __init, _BinaryOp __b, _UnaryOp __u)
232 for (; __first != __last; ++__first)
233 __init = __b(__init, __u(*__first));
237 template <class _InputIterator1, class _InputIterator2,
238 class _Tp, class _BinaryOp1, class _BinaryOp2>
239 inline _LIBCPP_INLINE_VISIBILITY
241 transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
242 _InputIterator2 __first2, _Tp __init, _BinaryOp1 __b1, _BinaryOp2 __b2)
244 for (; __first1 != __last1; ++__first1, (void) ++__first2)
245 __init = __b1(__init, __b2(*__first1, *__first2));
249 template <class _InputIterator1, class _InputIterator2, class _Tp>
250 inline _LIBCPP_INLINE_VISIBILITY
252 transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
253 _InputIterator2 __first2, _Tp __init)
255 return _VSTD::transform_reduce(__first1, __last1, __first2, __init,
256 _VSTD::plus<>(), _VSTD::multiplies<>());
260 template <class _InputIterator, class _OutputIterator>
261 inline _LIBCPP_INLINE_VISIBILITY
263 partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
265 if (__first != __last)
267 typename iterator_traits<_InputIterator>::value_type __t(*__first);
269 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
271 __t = __t + *__first;
278 template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
279 inline _LIBCPP_INLINE_VISIBILITY
281 partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
282 _BinaryOperation __binary_op)
284 if (__first != __last)
286 typename iterator_traits<_InputIterator>::value_type __t(*__first);
288 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
290 __t = __binary_op(__t, *__first);
297 #if _LIBCPP_STD_VER > 14
298 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
299 inline _LIBCPP_INLINE_VISIBILITY
301 exclusive_scan(_InputIterator __first, _InputIterator __last,
302 _OutputIterator __result, _Tp __init, _BinaryOp __b)
304 if (__first != __last)
306 _Tp __saved = __init;
309 __init = __b(__init, *__first);
313 } while (++__first != __last);
318 template <class _InputIterator, class _OutputIterator, class _Tp>
319 inline _LIBCPP_INLINE_VISIBILITY
321 exclusive_scan(_InputIterator __first, _InputIterator __last,
322 _OutputIterator __result, _Tp __init)
324 return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>());
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)
331 for (; __first != __last; ++__first, (void) ++__result) {
332 __init = __b(__init, *__first);
338 template <class _InputIterator, class _OutputIterator, class _BinaryOp>
339 _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
340 _OutputIterator __result, _BinaryOp __b)
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);
352 template <class _InputIterator, class _OutputIterator>
353 _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
354 _OutputIterator __result)
356 return _VSTD::inclusive_scan(__first, __last, __result, std::plus<>());
359 template <class _InputIterator, class _OutputIterator, class _Tp,
360 class _BinaryOp, class _UnaryOp>
361 inline _LIBCPP_INLINE_VISIBILITY
363 transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
364 _OutputIterator __result, _Tp __init,
365 _BinaryOp __b, _UnaryOp __u)
367 if (__first != __last)
369 _Tp __saved = __init;
372 __init = __b(__init, __u(*__first));
376 } while (++__first != __last);
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)
385 for (; __first != __last; ++__first, (void) ++__result) {
386 __init = __b(__init, __u(*__first));
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)
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);
408 template <class _InputIterator, class _OutputIterator>
409 inline _LIBCPP_INLINE_VISIBILITY
411 adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
413 if (__first != __last)
415 typename iterator_traits<_InputIterator>::value_type __t1(*__first);
417 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
419 typename iterator_traits<_InputIterator>::value_type __t2(*__first);
420 *__result = __t2 - __t1;
421 __t1 = _VSTD::move(__t2);
427 template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
428 inline _LIBCPP_INLINE_VISIBILITY
430 adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
431 _BinaryOperation __binary_op)
433 if (__first != __last)
435 typename iterator_traits<_InputIterator>::value_type __t1(*__first);
437 for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
439 typename iterator_traits<_InputIterator>::value_type __t2(*__first);
440 *__result = __binary_op(__t2, __t1);
441 __t1 = _VSTD::move(__t2);
447 template <class _ForwardIterator, class _Tp>
448 inline _LIBCPP_INLINE_VISIBILITY
450 iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)
452 for (; __first != __last; ++__first, (void) ++__value_)
457 #if _LIBCPP_STD_VER > 14
458 template <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __abs;
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
465 if (__t >= 0) return __t;
466 if (__t == numeric_limits<_Source>::min()) return -static_cast<_Result>(__t);
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; }
479 _LIBCPP_CONSTEXPR _LIBCPP_HIDDEN
480 _Tp __gcd(_Tp __m, _Tp __n)
482 static_assert((!is_signed<_Tp>::value), "");
483 return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n);
487 template<class _Tp, class _Up>
488 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
489 common_type_t<_Tp,_Up>
490 gcd(_Tp __m, _Up __n)
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))));
502 template<class _Tp, class _Up>
503 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
504 common_type_t<_Tp,_Up>
505 lcm(_Tp __m, _Up __n)
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)
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;
520 #endif /* _LIBCPP_STD_VER > 14 */
522 _LIBCPP_END_NAMESPACE_STD
526 #endif // _LIBCPP_NUMERIC