// -*- C++ -*-
//===---------------------------- numeric ---------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_NUMERIC
#define _LIBCPP_NUMERIC

/*
    numeric synopsis

namespace std
{

template <class InputIterator, class T>
    T
    accumulate(InputIterator first, InputIterator last, T init);

template <class InputIterator, class T, class BinaryOperation>
    T
    accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);

template <class InputIterator1, class InputIterator2, class T>
    T
    inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);

template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
    T
    inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
                  T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);

template <class InputIterator, class OutputIterator>
    OutputIterator
    partial_sum(InputIterator first, InputIterator last, OutputIterator result);

template <class InputIterator, class OutputIterator, class BinaryOperation>
    OutputIterator
    partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);

template <class InputIterator, class OutputIterator>
    OutputIterator
    adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);

template <class InputIterator, class OutputIterator, class BinaryOperation>
    OutputIterator
    adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);

template <class ForwardIterator, class T>
    void iota(ForwardIterator first, ForwardIterator last, T value);

}  // std

*/

#include <__config>
#include <iterator>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
    for (; __first != __last; ++__first)
        __init = __init + *__first;
    return __init;
}

template <class _InputIterator, class _Tp, class _BinaryOperation>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
{
    for (; __first != __last; ++__first)
        __init = __binary_op(__init, *__first);
    return __init;
}

template <class _InputIterator1, class _InputIterator2, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
{
    for (; __first1 != __last1; ++__first1, ++__first2)
        __init = __init + *__first1 * *__first2;
    return __init;
}

template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
              _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
{
    for (; __first1 != __last1; ++__first1, ++__first2)
        __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
    return __init;
}

template <class _InputIterator, class _OutputIterator>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
{
    if (__first != __last)
    {
        typename iterator_traits<_InputIterator>::value_type __t(*__first);
        *__result = __t;
        for (++__first, ++__result; __first != __last; ++__first, ++__result)
        {
            __t = __t + *__first;
            *__result = __t;
        }
    }
    return __result;
}

template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
              _BinaryOperation __binary_op)
{
    if (__first != __last)
    {
        typename iterator_traits<_InputIterator>::value_type __t(*__first);
        *__result = __t;
        for (++__first, ++__result; __first != __last; ++__first, ++__result)
        {
            __t = __binary_op(__t, *__first);
            *__result = __t;
        }
    }
    return __result;
}

template <class _InputIterator, class _OutputIterator>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
{
    if (__first != __last)
    {
        typename iterator_traits<_InputIterator>::value_type __t1(*__first);
        *__result = __t1;
        for (++__first, ++__result; __first != __last; ++__first, ++__result)
        {
            typename iterator_traits<_InputIterator>::value_type __t2(*__first);
            *__result = __t2 - __t1;
            __t1 = __t2;
        }
    }
    return __result;
}

template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
                      _BinaryOperation __binary_op)
{
    if (__first != __last)
    {
        typename iterator_traits<_InputIterator>::value_type __t1(*__first);
        *__result = __t1;
        for (++__first, ++__result; __first != __last; ++__first, ++__result)
        {
            typename iterator_traits<_InputIterator>::value_type __t2(*__first);
            *__result = __binary_op(__t2, __t1);
            __t1 = __t2;
        }
    }
    return __result;
}

template <class _ForwardIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
void
iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)
{
    for (; __first != __last; ++__first, ++__value_)
        *__first = __value_;
}

_LIBCPP_END_NAMESPACE_STD

#endif  // _LIBCPP_NUMERIC
