xref: /freebsd-12.1/contrib/libc++/include/numeric (revision b5893f02)
17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===---------------------------- numeric ---------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open
77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP_NUMERIC
127a984708SDavid Chisnall#define _LIBCPP_NUMERIC
137a984708SDavid Chisnall
147a984708SDavid Chisnall/*
157a984708SDavid Chisnall    numeric synopsis
167a984708SDavid Chisnall
177a984708SDavid Chisnallnamespace std
187a984708SDavid Chisnall{
197a984708SDavid Chisnall
207a984708SDavid Chisnalltemplate <class InputIterator, class T>
217a984708SDavid Chisnall    T
227a984708SDavid Chisnall    accumulate(InputIterator first, InputIterator last, T init);
237a984708SDavid Chisnall
247a984708SDavid Chisnalltemplate <class InputIterator, class T, class BinaryOperation>
257a984708SDavid Chisnall    T
267a984708SDavid Chisnall    accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
277a984708SDavid Chisnall
2824d58133SDimitry Andrictemplate<class InputIterator>
2924d58133SDimitry Andric    typename iterator_traits<InputIterator>::value_type
3024d58133SDimitry Andric    reduce(InputIterator first, InputIterator last);  // C++17
3124d58133SDimitry Andric
3224d58133SDimitry Andrictemplate<class InputIterator, class T>
3324d58133SDimitry Andric    T
3424d58133SDimitry Andric    reduce(InputIterator first, InputIterator last, T init);  // C++17
3524d58133SDimitry Andric
3624d58133SDimitry Andrictemplate<class InputIterator, class T, class BinaryOperation>
3724d58133SDimitry Andric    T
3824d58133SDimitry Andric    reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);  // C++17
3924d58133SDimitry Andric
407a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class T>
417a984708SDavid Chisnall    T
427a984708SDavid Chisnall    inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);
437a984708SDavid Chisnall
447a984708SDavid Chisnalltemplate <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
457a984708SDavid Chisnall    T
467a984708SDavid Chisnall    inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
477a984708SDavid Chisnall                  T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
487a984708SDavid Chisnall
4924d58133SDimitry Andric
5024d58133SDimitry Andrictemplate<class InputIterator1, class InputIterator2, class T>
5124d58133SDimitry Andric    T
5224d58133SDimitry Andric    transform_reduce(InputIterator1 first1, InputIterator1 last1,
5324d58133SDimitry Andric                     InputIterator2 first2, T init);  // C++17
5424d58133SDimitry Andric
5524d58133SDimitry Andrictemplate<class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
5624d58133SDimitry Andric    T
5724d58133SDimitry Andric    transform_reduce(InputIterator1 first1, InputIterator1 last1,
5824d58133SDimitry Andric                     InputIterator2 first2, T init,
5924d58133SDimitry Andric                     BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);  // C++17
6024d58133SDimitry Andric
6124d58133SDimitry Andrictemplate<class InputIterator, class T, class BinaryOperation, class UnaryOperation>
6224d58133SDimitry Andric    T
6324d58133SDimitry Andric    transform_reduce(InputIterator first, InputIterator last, T init,
6424d58133SDimitry Andric                     BinaryOperation binary_op, UnaryOperation unary_op);  // C++17
6524d58133SDimitry Andric
667a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator>
677a984708SDavid Chisnall    OutputIterator
687a984708SDavid Chisnall    partial_sum(InputIterator first, InputIterator last, OutputIterator result);
697a984708SDavid Chisnall
707a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator, class BinaryOperation>
717a984708SDavid Chisnall    OutputIterator
727a984708SDavid Chisnall    partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
737a984708SDavid Chisnall
74db17bf38SDimitry Andrictemplate<class InputIterator, class OutputIterator, class T>
75db17bf38SDimitry Andric    OutputIterator
76db17bf38SDimitry Andric    exclusive_scan(InputIterator first, InputIterator last,
77db17bf38SDimitry Andric                   OutputIterator result, T init); // C++17
78db17bf38SDimitry Andric
79db17bf38SDimitry Andrictemplate<class InputIterator, class OutputIterator, class T, class BinaryOperation>
80db17bf38SDimitry Andric    OutputIterator
81db17bf38SDimitry Andric    exclusive_scan(InputIterator first, InputIterator last,
82db17bf38SDimitry Andric                   OutputIterator result, T init, BinaryOperation binary_op); // C++17
83db17bf38SDimitry Andric
84edd7eaddSDimitry Andrictemplate<class InputIterator, class OutputIterator>
85edd7eaddSDimitry Andric    OutputIterator
86edd7eaddSDimitry Andric    inclusive_scan(InputIterator first, InputIterator last, OutputIterator result);  // C++17
87edd7eaddSDimitry Andric
88edd7eaddSDimitry Andrictemplate<class InputIterator, class OutputIterator, class BinaryOperation>
89edd7eaddSDimitry Andric    OutputIterator
90edd7eaddSDimitry Andric    inclusive_scan(InputIterator first, InputIterator last,
91edd7eaddSDimitry Andric                   OutputIterator result, BinaryOperation binary_op);  // C++17
92edd7eaddSDimitry Andric
93edd7eaddSDimitry Andrictemplate<class InputIterator, class OutputIterator, class BinaryOperation, class T>
94edd7eaddSDimitry Andric    OutputIterator
95edd7eaddSDimitry Andric    inclusive_scan(InputIterator first, InputIterator last,
96edd7eaddSDimitry Andric                   OutputIterator result, BinaryOperation binary_op, T init);  // C++17
97edd7eaddSDimitry Andric
98db17bf38SDimitry Andrictemplate<class InputIterator, class OutputIterator, class T,
99db17bf38SDimitry Andric         class BinaryOperation, class UnaryOperation>
100db17bf38SDimitry Andric    OutputIterator
101db17bf38SDimitry Andric    transform_exclusive_scan(InputIterator first, InputIterator last,
102db17bf38SDimitry Andric                             OutputIterator result, T init,
103db17bf38SDimitry Andric                             BinaryOperation binary_op, UnaryOperation unary_op);  // C++17
104db17bf38SDimitry Andric
105edd7eaddSDimitry Andrictemplate<class InputIterator, class OutputIterator,
106edd7eaddSDimitry Andric         class BinaryOperation, class UnaryOperation>
107edd7eaddSDimitry Andric    OutputIterator
108edd7eaddSDimitry Andric    transform_inclusive_scan(InputIterator first, InputIterator last,
109edd7eaddSDimitry Andric                             OutputIterator result,
110edd7eaddSDimitry Andric                             BinaryOperation binary_op, UnaryOperation unary_op);  // C++17
111edd7eaddSDimitry Andric
112edd7eaddSDimitry Andrictemplate<class InputIterator, class OutputIterator,
113edd7eaddSDimitry Andric         class BinaryOperation, class UnaryOperation, class T>
114edd7eaddSDimitry Andric    OutputIterator
115edd7eaddSDimitry Andric    transform_inclusive_scan(InputIterator first, InputIterator last,
116edd7eaddSDimitry Andric                             OutputIterator result,
117edd7eaddSDimitry Andric                             BinaryOperation binary_op, UnaryOperation unary_op,
118edd7eaddSDimitry Andric                             T init);  // C++17
119edd7eaddSDimitry Andric
1207a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator>
1217a984708SDavid Chisnall    OutputIterator
1227a984708SDavid Chisnall    adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);
1237a984708SDavid Chisnall
1247a984708SDavid Chisnalltemplate <class InputIterator, class OutputIterator, class BinaryOperation>
1257a984708SDavid Chisnall    OutputIterator
1267a984708SDavid Chisnall    adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
1277a984708SDavid Chisnall
1287a984708SDavid Chisnalltemplate <class ForwardIterator, class T>
1297a984708SDavid Chisnall    void iota(ForwardIterator first, ForwardIterator last, T value);
1307a984708SDavid Chisnall
131aed8d94eSDimitry Andrictemplate <class M, class N>
132aed8d94eSDimitry Andric    constexpr common_type_t<M,N> gcd(M m, N n);    // C++17
133aed8d94eSDimitry Andric
134aed8d94eSDimitry Andrictemplate <class M, class N>
135aed8d94eSDimitry Andric    constexpr common_type_t<M,N> lcm(M m, N n);    // C++17
136aed8d94eSDimitry Andric
1377a984708SDavid Chisnall}  // std
1387a984708SDavid Chisnall
1397a984708SDavid Chisnall*/
1407a984708SDavid Chisnall
1417a984708SDavid Chisnall#include <__config>
1427a984708SDavid Chisnall#include <iterator>
143540d2a8bSDimitry Andric#include <limits> // for numeric_limits
144db17bf38SDimitry Andric#include <functional>
145*b5893f02SDimitry Andric#include <version>
1467a984708SDavid Chisnall
1477a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1487a984708SDavid Chisnall#pragma GCC system_header
1497a984708SDavid Chisnall#endif
1507a984708SDavid Chisnall
151f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS
152f9448bf3SDimitry Andric#include <__undef_macros>
153f9448bf3SDimitry Andric
1547a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
1557a984708SDavid Chisnall
1567a984708SDavid Chisnalltemplate <class _InputIterator, class _Tp>
1577a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
1587a984708SDavid Chisnall_Tp
1597a984708SDavid Chisnallaccumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
1607a984708SDavid Chisnall{
1617a984708SDavid Chisnall    for (; __first != __last; ++__first)
1627a984708SDavid Chisnall        __init = __init + *__first;
1637a984708SDavid Chisnall    return __init;
1647a984708SDavid Chisnall}
1657a984708SDavid Chisnall
1667a984708SDavid Chisnalltemplate <class _InputIterator, class _Tp, class _BinaryOperation>
1677a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
1687a984708SDavid Chisnall_Tp
1697a984708SDavid Chisnallaccumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
1707a984708SDavid Chisnall{
1717a984708SDavid Chisnall    for (; __first != __last; ++__first)
1727a984708SDavid Chisnall        __init = __binary_op(__init, *__first);
1737a984708SDavid Chisnall    return __init;
1747a984708SDavid Chisnall}
1757a984708SDavid Chisnall
17624d58133SDimitry Andric#if _LIBCPP_STD_VER > 14
17724d58133SDimitry Andrictemplate <class _InputIterator, class _Tp, class _BinaryOp>
17824d58133SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
17924d58133SDimitry Andric_Tp
18024d58133SDimitry Andricreduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b)
18124d58133SDimitry Andric{
18224d58133SDimitry Andric    for (; __first != __last; ++__first)
18324d58133SDimitry Andric        __init = __b(__init, *__first);
18424d58133SDimitry Andric    return __init;
18524d58133SDimitry Andric}
18624d58133SDimitry Andric
18724d58133SDimitry Andrictemplate <class _InputIterator, class _Tp>
18824d58133SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
18924d58133SDimitry Andric_Tp
19024d58133SDimitry Andricreduce(_InputIterator __first, _InputIterator __last, _Tp __init)
19124d58133SDimitry Andric{
19224d58133SDimitry Andric    return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>());
19324d58133SDimitry Andric}
19424d58133SDimitry Andric
19524d58133SDimitry Andrictemplate <class _InputIterator>
19624d58133SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19724d58133SDimitry Andrictypename iterator_traits<_InputIterator>::value_type
19824d58133SDimitry Andricreduce(_InputIterator __first, _InputIterator __last)
19924d58133SDimitry Andric{
20024d58133SDimitry Andric    return _VSTD::reduce(__first, __last,
20124d58133SDimitry Andric       typename iterator_traits<_InputIterator>::value_type{});
20224d58133SDimitry Andric}
20324d58133SDimitry Andric#endif
20424d58133SDimitry Andric
2057a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _Tp>
2067a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
2077a984708SDavid Chisnall_Tp
2087a984708SDavid Chisnallinner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
2097a984708SDavid Chisnall{
210d72607e9SDimitry Andric    for (; __first1 != __last1; ++__first1, (void) ++__first2)
2117a984708SDavid Chisnall        __init = __init + *__first1 * *__first2;
2127a984708SDavid Chisnall    return __init;
2137a984708SDavid Chisnall}
2147a984708SDavid Chisnall
2157a984708SDavid Chisnalltemplate <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
2167a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
2177a984708SDavid Chisnall_Tp
2187a984708SDavid Chisnallinner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
2197a984708SDavid Chisnall              _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
2207a984708SDavid Chisnall{
221d72607e9SDimitry Andric    for (; __first1 != __last1; ++__first1, (void) ++__first2)
2227a984708SDavid Chisnall        __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
2237a984708SDavid Chisnall    return __init;
2247a984708SDavid Chisnall}
2257a984708SDavid Chisnall
22624d58133SDimitry Andric#if _LIBCPP_STD_VER > 14
22724d58133SDimitry Andrictemplate <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
22824d58133SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
22924d58133SDimitry Andric_Tp
23024d58133SDimitry Andrictransform_reduce(_InputIterator __first, _InputIterator __last,
23124d58133SDimitry Andric           _Tp __init,  _BinaryOp __b, _UnaryOp __u)
23224d58133SDimitry Andric{
23324d58133SDimitry Andric    for (; __first != __last; ++__first)
23424d58133SDimitry Andric        __init = __b(__init, __u(*__first));
23524d58133SDimitry Andric    return __init;
23624d58133SDimitry Andric}
23724d58133SDimitry Andric
23824d58133SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2,
23924d58133SDimitry Andric          class _Tp, class _BinaryOp1, class _BinaryOp2>
24024d58133SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
24124d58133SDimitry Andric_Tp
24224d58133SDimitry Andrictransform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
24324d58133SDimitry Andric                 _InputIterator2 __first2, _Tp __init,  _BinaryOp1 __b1, _BinaryOp2 __b2)
24424d58133SDimitry Andric{
24524d58133SDimitry Andric    for (; __first1 != __last1; ++__first1, (void) ++__first2)
24624d58133SDimitry Andric        __init = __b1(__init, __b2(*__first1, *__first2));
24724d58133SDimitry Andric    return __init;
24824d58133SDimitry Andric}
24924d58133SDimitry Andric
25024d58133SDimitry Andrictemplate <class _InputIterator1, class _InputIterator2, class _Tp>
25124d58133SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
25224d58133SDimitry Andric_Tp
25324d58133SDimitry Andrictransform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
25424d58133SDimitry Andric                 _InputIterator2 __first2, _Tp __init)
25524d58133SDimitry Andric{
2564ba319b5SDimitry Andric    return _VSTD::transform_reduce(__first1, __last1, __first2, _VSTD::move(__init),
25724d58133SDimitry Andric                                   _VSTD::plus<>(), _VSTD::multiplies<>());
25824d58133SDimitry Andric}
25924d58133SDimitry Andric#endif
26024d58133SDimitry Andric
2617a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator>
2627a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
2637a984708SDavid Chisnall_OutputIterator
2647a984708SDavid Chisnallpartial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
2657a984708SDavid Chisnall{
2667a984708SDavid Chisnall    if (__first != __last)
2677a984708SDavid Chisnall    {
2687a984708SDavid Chisnall        typename iterator_traits<_InputIterator>::value_type __t(*__first);
2697a984708SDavid Chisnall        *__result = __t;
270d72607e9SDimitry Andric        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
2717a984708SDavid Chisnall        {
2727a984708SDavid Chisnall            __t = __t + *__first;
2737a984708SDavid Chisnall            *__result = __t;
2747a984708SDavid Chisnall        }
2757a984708SDavid Chisnall    }
2767a984708SDavid Chisnall    return __result;
2777a984708SDavid Chisnall}
2787a984708SDavid Chisnall
2797a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator, class _BinaryOperation>
2807a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
2817a984708SDavid Chisnall_OutputIterator
2827a984708SDavid Chisnallpartial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
2837a984708SDavid Chisnall              _BinaryOperation __binary_op)
2847a984708SDavid Chisnall{
2857a984708SDavid Chisnall    if (__first != __last)
2867a984708SDavid Chisnall    {
2877a984708SDavid Chisnall        typename iterator_traits<_InputIterator>::value_type __t(*__first);
2887a984708SDavid Chisnall        *__result = __t;
289d72607e9SDimitry Andric        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
2907a984708SDavid Chisnall        {
2917a984708SDavid Chisnall            __t = __binary_op(__t, *__first);
2927a984708SDavid Chisnall            *__result = __t;
2937a984708SDavid Chisnall        }
2947a984708SDavid Chisnall    }
2957a984708SDavid Chisnall    return __result;
2967a984708SDavid Chisnall}
2977a984708SDavid Chisnall
298db17bf38SDimitry Andric#if _LIBCPP_STD_VER > 14
299db17bf38SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
300db17bf38SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
301db17bf38SDimitry Andric_OutputIterator
302db17bf38SDimitry Andricexclusive_scan(_InputIterator __first, _InputIterator __last,
303db17bf38SDimitry Andric               _OutputIterator __result, _Tp __init, _BinaryOp __b)
304db17bf38SDimitry Andric{
305db17bf38SDimitry Andric    if (__first != __last)
306db17bf38SDimitry Andric    {
307db17bf38SDimitry Andric        _Tp __saved = __init;
308db17bf38SDimitry Andric        do
309db17bf38SDimitry Andric        {
310db17bf38SDimitry Andric            __init = __b(__init, *__first);
311db17bf38SDimitry Andric            *__result = __saved;
312db17bf38SDimitry Andric            __saved = __init;
313db17bf38SDimitry Andric            ++__result;
314db17bf38SDimitry Andric        } while (++__first != __last);
315db17bf38SDimitry Andric    }
316db17bf38SDimitry Andric    return __result;
317db17bf38SDimitry Andric}
318db17bf38SDimitry Andric
319db17bf38SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp>
320db17bf38SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
321db17bf38SDimitry Andric_OutputIterator
322db17bf38SDimitry Andricexclusive_scan(_InputIterator __first, _InputIterator __last,
323db17bf38SDimitry Andric               _OutputIterator __result, _Tp __init)
324db17bf38SDimitry Andric{
325db17bf38SDimitry Andric    return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>());
326db17bf38SDimitry Andric}
327db17bf38SDimitry Andric
328edd7eaddSDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
329edd7eaddSDimitry Andric_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
330edd7eaddSDimitry Andric                               _OutputIterator __result, _BinaryOp __b,  _Tp __init)
331edd7eaddSDimitry Andric{
332edd7eaddSDimitry Andric    for (; __first != __last; ++__first, (void) ++__result) {
333edd7eaddSDimitry Andric        __init = __b(__init, *__first);
334edd7eaddSDimitry Andric        *__result = __init;
335edd7eaddSDimitry Andric        }
336edd7eaddSDimitry Andric    return __result;
337edd7eaddSDimitry Andric}
338edd7eaddSDimitry Andric
339edd7eaddSDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _BinaryOp>
340edd7eaddSDimitry Andric_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
341edd7eaddSDimitry Andric                               _OutputIterator __result, _BinaryOp __b)
342edd7eaddSDimitry Andric{
343edd7eaddSDimitry Andric    if (__first != __last) {
344edd7eaddSDimitry Andric        typename std::iterator_traits<_InputIterator>::value_type __init = *__first;
345edd7eaddSDimitry Andric        *__result++ = __init;
346edd7eaddSDimitry Andric        if (++__first != __last)
347edd7eaddSDimitry Andric            return _VSTD::inclusive_scan(__first, __last, __result, __b, __init);
348edd7eaddSDimitry Andric        }
349edd7eaddSDimitry Andric
350edd7eaddSDimitry Andric    return __result;
351edd7eaddSDimitry Andric}
352edd7eaddSDimitry Andric
353edd7eaddSDimitry Andrictemplate <class _InputIterator, class _OutputIterator>
354edd7eaddSDimitry Andric_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
355edd7eaddSDimitry Andric                               _OutputIterator __result)
356edd7eaddSDimitry Andric{
357edd7eaddSDimitry Andric    return _VSTD::inclusive_scan(__first, __last, __result, std::plus<>());
358edd7eaddSDimitry Andric}
359edd7eaddSDimitry Andric
360db17bf38SDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp,
361db17bf38SDimitry Andric          class _BinaryOp, class _UnaryOp>
362db17bf38SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
363db17bf38SDimitry Andric_OutputIterator
364db17bf38SDimitry Andrictransform_exclusive_scan(_InputIterator __first, _InputIterator __last,
365db17bf38SDimitry Andric                           _OutputIterator __result, _Tp __init,
366db17bf38SDimitry Andric                           _BinaryOp __b, _UnaryOp __u)
367db17bf38SDimitry Andric{
368db17bf38SDimitry Andric    if (__first != __last)
369db17bf38SDimitry Andric    {
370db17bf38SDimitry Andric        _Tp __saved = __init;
371db17bf38SDimitry Andric        do
372db17bf38SDimitry Andric        {
373db17bf38SDimitry Andric            __init = __b(__init, __u(*__first));
374db17bf38SDimitry Andric            *__result = __saved;
375db17bf38SDimitry Andric            __saved = __init;
376db17bf38SDimitry Andric            ++__result;
377db17bf38SDimitry Andric        } while (++__first != __last);
378db17bf38SDimitry Andric    }
379db17bf38SDimitry Andric    return __result;
380db17bf38SDimitry Andric}
381edd7eaddSDimitry Andric
382edd7eaddSDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
383edd7eaddSDimitry Andric_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
384edd7eaddSDimitry Andric                           _OutputIterator __result, _BinaryOp __b, _UnaryOp __u, _Tp __init)
385edd7eaddSDimitry Andric{
386edd7eaddSDimitry Andric    for (; __first != __last; ++__first, (void) ++__result) {
387edd7eaddSDimitry Andric        __init = __b(__init, __u(*__first));
388edd7eaddSDimitry Andric        *__result = __init;
389edd7eaddSDimitry Andric        }
390edd7eaddSDimitry Andric
391edd7eaddSDimitry Andric    return __result;
392edd7eaddSDimitry Andric}
393edd7eaddSDimitry Andric
394edd7eaddSDimitry Andrictemplate <class _InputIterator, class _OutputIterator, class _BinaryOp, class _UnaryOp>
395edd7eaddSDimitry Andric_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
396edd7eaddSDimitry Andric                               _OutputIterator __result, _BinaryOp __b, _UnaryOp __u)
397edd7eaddSDimitry Andric{
398edd7eaddSDimitry Andric    if (__first != __last) {
399edd7eaddSDimitry Andric        typename std::iterator_traits<_InputIterator>::value_type __init = __u(*__first);
400edd7eaddSDimitry Andric        *__result++ = __init;
401edd7eaddSDimitry Andric        if (++__first != __last)
402edd7eaddSDimitry Andric            return _VSTD::transform_inclusive_scan(__first, __last, __result, __b, __u, __init);
403edd7eaddSDimitry Andric        }
404edd7eaddSDimitry Andric
405edd7eaddSDimitry Andric    return __result;
406edd7eaddSDimitry Andric}
407db17bf38SDimitry Andric#endif
408db17bf38SDimitry Andric
4097a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator>
4107a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4117a984708SDavid Chisnall_OutputIterator
4127a984708SDavid Chisnalladjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
4137a984708SDavid Chisnall{
4147a984708SDavid Chisnall    if (__first != __last)
4157a984708SDavid Chisnall    {
4167a984708SDavid Chisnall        typename iterator_traits<_InputIterator>::value_type __t1(*__first);
4177a984708SDavid Chisnall        *__result = __t1;
418d72607e9SDimitry Andric        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
4197a984708SDavid Chisnall        {
4207a984708SDavid Chisnall            typename iterator_traits<_InputIterator>::value_type __t2(*__first);
4217a984708SDavid Chisnall            *__result = __t2 - __t1;
4224f7ab58eSDimitry Andric            __t1 = _VSTD::move(__t2);
4237a984708SDavid Chisnall        }
4247a984708SDavid Chisnall    }
4257a984708SDavid Chisnall    return __result;
4267a984708SDavid Chisnall}
4277a984708SDavid Chisnall
4287a984708SDavid Chisnalltemplate <class _InputIterator, class _OutputIterator, class _BinaryOperation>
4297a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4307a984708SDavid Chisnall_OutputIterator
4317a984708SDavid Chisnalladjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
4327a984708SDavid Chisnall                      _BinaryOperation __binary_op)
4337a984708SDavid Chisnall{
4347a984708SDavid Chisnall    if (__first != __last)
4357a984708SDavid Chisnall    {
4367a984708SDavid Chisnall        typename iterator_traits<_InputIterator>::value_type __t1(*__first);
4377a984708SDavid Chisnall        *__result = __t1;
438d72607e9SDimitry Andric        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
4397a984708SDavid Chisnall        {
4407a984708SDavid Chisnall            typename iterator_traits<_InputIterator>::value_type __t2(*__first);
4417a984708SDavid Chisnall            *__result = __binary_op(__t2, __t1);
4424f7ab58eSDimitry Andric            __t1 = _VSTD::move(__t2);
4437a984708SDavid Chisnall        }
4447a984708SDavid Chisnall    }
4457a984708SDavid Chisnall    return __result;
4467a984708SDavid Chisnall}
4477a984708SDavid Chisnall
4487a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp>
4497a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4507a984708SDavid Chisnallvoid
4517a984708SDavid Chisnalliota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)
4527a984708SDavid Chisnall{
453d72607e9SDimitry Andric    for (; __first != __last; ++__first, (void) ++__value_)
4547a984708SDavid Chisnall        *__first = __value_;
4557a984708SDavid Chisnall}
4567a984708SDavid Chisnall
457aed8d94eSDimitry Andric
458aed8d94eSDimitry Andric#if _LIBCPP_STD_VER > 14
459540d2a8bSDimitry Andrictemplate <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __abs;
460aed8d94eSDimitry Andric
461540d2a8bSDimitry Andrictemplate <typename _Result, typename _Source>
462540d2a8bSDimitry Andricstruct __abs<_Result, _Source, true> {
463aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
464540d2a8bSDimitry Andric    _Result operator()(_Source __t) const noexcept
465540d2a8bSDimitry Andric    {
466540d2a8bSDimitry Andric    if (__t >= 0) return __t;
467540d2a8bSDimitry Andric    if (__t == numeric_limits<_Source>::min()) return -static_cast<_Result>(__t);
468540d2a8bSDimitry Andric    return -__t;
469540d2a8bSDimitry Andric    }
470aed8d94eSDimitry Andric};
471aed8d94eSDimitry Andric
472540d2a8bSDimitry Andrictemplate <typename _Result, typename _Source>
473540d2a8bSDimitry Andricstruct __abs<_Result, _Source, false> {
474aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
475540d2a8bSDimitry Andric    _Result operator()(_Source __t) const noexcept { return __t; }
476aed8d94eSDimitry Andric};
477aed8d94eSDimitry Andric
478aed8d94eSDimitry Andric
479aed8d94eSDimitry Andrictemplate<class _Tp>
4805517e702SDimitry Andric_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN
481aed8d94eSDimitry Andric_Tp __gcd(_Tp __m, _Tp __n)
482aed8d94eSDimitry Andric{
483aed8d94eSDimitry Andric    static_assert((!is_signed<_Tp>::value), "");
4845517e702SDimitry Andric    return __n == 0 ? __m : _VSTD::__gcd<_Tp>(__n, __m % __n);
485aed8d94eSDimitry Andric}
486aed8d94eSDimitry Andric
487aed8d94eSDimitry Andric
488aed8d94eSDimitry Andrictemplate<class _Tp, class _Up>
489aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
490aed8d94eSDimitry Andriccommon_type_t<_Tp,_Up>
491aed8d94eSDimitry Andricgcd(_Tp __m, _Up __n)
492aed8d94eSDimitry Andric{
493aed8d94eSDimitry Andric    static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types");
494aed8d94eSDimitry Andric    static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to gcd cannot be bool" );
495aed8d94eSDimitry Andric    static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to gcd cannot be bool" );
496aed8d94eSDimitry Andric    using _Rp = common_type_t<_Tp,_Up>;
497aed8d94eSDimitry Andric    using _Wp = make_unsigned_t<_Rp>;
4985517e702SDimitry Andric    return static_cast<_Rp>(_VSTD::__gcd(
4995517e702SDimitry Andric        static_cast<_Wp>(__abs<_Rp, _Tp>()(__m)),
500540d2a8bSDimitry Andric        static_cast<_Wp>(__abs<_Rp, _Up>()(__n))));
501aed8d94eSDimitry Andric}
502aed8d94eSDimitry Andric
503aed8d94eSDimitry Andrictemplate<class _Tp, class _Up>
504aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
505aed8d94eSDimitry Andriccommon_type_t<_Tp,_Up>
506aed8d94eSDimitry Andriclcm(_Tp __m, _Up __n)
507aed8d94eSDimitry Andric{
508aed8d94eSDimitry Andric    static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types");
509aed8d94eSDimitry Andric    static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to lcm cannot be bool" );
510aed8d94eSDimitry Andric    static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to lcm cannot be bool" );
511aed8d94eSDimitry Andric    if (__m == 0 || __n == 0)
512aed8d94eSDimitry Andric        return 0;
513aed8d94eSDimitry Andric
514aed8d94eSDimitry Andric    using _Rp = common_type_t<_Tp,_Up>;
5155517e702SDimitry Andric    _Rp __val1 = __abs<_Rp, _Tp>()(__m) / _VSTD::gcd(__m, __n);
516540d2a8bSDimitry Andric    _Rp __val2 = __abs<_Rp, _Up>()(__n);
517aed8d94eSDimitry Andric    _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm");
518aed8d94eSDimitry Andric    return __val1 * __val2;
519aed8d94eSDimitry Andric}
520aed8d94eSDimitry Andric
521aed8d94eSDimitry Andric#endif /* _LIBCPP_STD_VER > 14 */
522aed8d94eSDimitry Andric
5237a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
5247a984708SDavid Chisnall
525f9448bf3SDimitry Andric_LIBCPP_POP_MACROS
526f9448bf3SDimitry Andric
5277a984708SDavid Chisnall#endif  // _LIBCPP_NUMERIC
528