14fee23f9Smrg // Numeric functions implementation -*- C++ -*-
24fee23f9Smrg
3b1e83836Smrg // Copyright (C) 2001-2022 Free Software Foundation, Inc.
44fee23f9Smrg //
54fee23f9Smrg // This file is part of the GNU ISO C++ Library. This library is free
64fee23f9Smrg // software; you can redistribute it and/or modify it under the
74fee23f9Smrg // terms of the GNU General Public License as published by the
84fee23f9Smrg // Free Software Foundation; either version 3, or (at your option)
94fee23f9Smrg // any later version.
104fee23f9Smrg
114fee23f9Smrg // This library is distributed in the hope that it will be useful,
124fee23f9Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
134fee23f9Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
144fee23f9Smrg // GNU General Public License for more details.
154fee23f9Smrg
164fee23f9Smrg // Under Section 7 of GPL version 3, you are granted additional
174fee23f9Smrg // permissions described in the GCC Runtime Library Exception, version
184fee23f9Smrg // 3.1, as published by the Free Software Foundation.
194fee23f9Smrg
204fee23f9Smrg // You should have received a copy of the GNU General Public License and
214fee23f9Smrg // a copy of the GCC Runtime Library Exception along with this program;
224fee23f9Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
234fee23f9Smrg // <http://www.gnu.org/licenses/>.
244fee23f9Smrg
254fee23f9Smrg /*
264fee23f9Smrg *
274fee23f9Smrg * Copyright (c) 1994
284fee23f9Smrg * Hewlett-Packard Company
294fee23f9Smrg *
304fee23f9Smrg * Permission to use, copy, modify, distribute and sell this software
314fee23f9Smrg * and its documentation for any purpose is hereby granted without fee,
324fee23f9Smrg * provided that the above copyright notice appear in all copies and
334fee23f9Smrg * that both that copyright notice and this permission notice appear
344fee23f9Smrg * in supporting documentation. Hewlett-Packard Company makes no
354fee23f9Smrg * representations about the suitability of this software for any
364fee23f9Smrg * purpose. It is provided "as is" without express or implied warranty.
374fee23f9Smrg *
384fee23f9Smrg *
394fee23f9Smrg * Copyright (c) 1996,1997
404fee23f9Smrg * Silicon Graphics Computer Systems, Inc.
414fee23f9Smrg *
424fee23f9Smrg * Permission to use, copy, modify, distribute and sell this software
434fee23f9Smrg * and its documentation for any purpose is hereby granted without fee,
444fee23f9Smrg * provided that the above copyright notice appear in all copies and
454fee23f9Smrg * that both that copyright notice and this permission notice appear
464fee23f9Smrg * in supporting documentation. Silicon Graphics makes no
474fee23f9Smrg * representations about the suitability of this software for any
484fee23f9Smrg * purpose. It is provided "as is" without express or implied warranty.
494fee23f9Smrg */
504fee23f9Smrg
5148fb7bfaSmrg /** @file bits/stl_numeric.h
524fee23f9Smrg * This is an internal header file, included by other library headers.
5348fb7bfaSmrg * Do not attempt to use it directly. @headername{numeric}
544fee23f9Smrg */
554fee23f9Smrg
564fee23f9Smrg #ifndef _STL_NUMERIC_H
574fee23f9Smrg #define _STL_NUMERIC_H 1
584fee23f9Smrg
594fee23f9Smrg #include <bits/concept_check.h>
604fee23f9Smrg #include <debug/debug.h>
614fee23f9Smrg #include <bits/move.h> // For _GLIBCXX_MOVE
624fee23f9Smrg
634fee23f9Smrg
_GLIBCXX_VISIBILITY(default)6448fb7bfaSmrg namespace std _GLIBCXX_VISIBILITY(default)
6548fb7bfaSmrg {
6648fb7bfaSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
674fee23f9Smrg
68181254a7Smrg /** @defgroup numeric_ops Generalized Numeric operations
69181254a7Smrg * @ingroup algorithms
70181254a7Smrg */
71181254a7Smrg
72181254a7Smrg #if __cplusplus >= 201103L
734fee23f9Smrg /**
744fee23f9Smrg * @brief Create a range of sequentially increasing values.
754fee23f9Smrg *
764fee23f9Smrg * For each element in the range @p [first,last) assigns @p value and
774fee23f9Smrg * increments @p value as if by @p ++value.
784fee23f9Smrg *
7948fb7bfaSmrg * @param __first Start of range.
8048fb7bfaSmrg * @param __last End of range.
8148fb7bfaSmrg * @param __value Starting value.
824fee23f9Smrg * @return Nothing.
83181254a7Smrg * @ingroup numeric_ops
844fee23f9Smrg */
854fee23f9Smrg template<typename _ForwardIterator, typename _Tp>
86fb8a8121Smrg _GLIBCXX20_CONSTEXPR
874fee23f9Smrg void
884fee23f9Smrg iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
894fee23f9Smrg {
904fee23f9Smrg // concept requirements
914fee23f9Smrg __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
924fee23f9Smrg _ForwardIterator>)
934fee23f9Smrg __glibcxx_function_requires(_ConvertibleConcept<_Tp,
944fee23f9Smrg typename iterator_traits<_ForwardIterator>::value_type>)
954fee23f9Smrg __glibcxx_requires_valid_range(__first, __last);
964fee23f9Smrg
974fee23f9Smrg for (; __first != __last; ++__first)
984fee23f9Smrg {
994fee23f9Smrg *__first = __value;
1004fee23f9Smrg ++__value;
1014fee23f9Smrg }
1024fee23f9Smrg }
1034fee23f9Smrg #endif
1044fee23f9Smrg
105181254a7Smrg _GLIBCXX_END_NAMESPACE_VERSION
106181254a7Smrg
10748fb7bfaSmrg _GLIBCXX_BEGIN_NAMESPACE_ALGO
1084fee23f9Smrg
109181254a7Smrg #if __cplusplus > 201703L
110181254a7Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
111181254a7Smrg // DR 2055. std::move in std::accumulate and other algorithms
112181254a7Smrg # define _GLIBCXX_MOVE_IF_20(_E) std::move(_E)
113181254a7Smrg #else
114181254a7Smrg # define _GLIBCXX_MOVE_IF_20(_E) _E
115181254a7Smrg #endif
116181254a7Smrg
117181254a7Smrg /// @addtogroup numeric_ops
118181254a7Smrg /// @{
119181254a7Smrg
1204fee23f9Smrg /**
1214fee23f9Smrg * @brief Accumulate values in a range.
1224fee23f9Smrg *
1234fee23f9Smrg * Accumulates the values in the range [first,last) using operator+(). The
1244fee23f9Smrg * initial value is @a init. The values are processed in order.
1254fee23f9Smrg *
12648fb7bfaSmrg * @param __first Start of range.
12748fb7bfaSmrg * @param __last End of range.
12848fb7bfaSmrg * @param __init Starting value to add other values to.
1294fee23f9Smrg * @return The final sum.
1304fee23f9Smrg */
1314fee23f9Smrg template<typename _InputIterator, typename _Tp>
132fb8a8121Smrg _GLIBCXX20_CONSTEXPR
1334fee23f9Smrg inline _Tp
1344fee23f9Smrg accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
1354fee23f9Smrg {
1364fee23f9Smrg // concept requirements
1374fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
1384fee23f9Smrg __glibcxx_requires_valid_range(__first, __last);
1394fee23f9Smrg
1404fee23f9Smrg for (; __first != __last; ++__first)
141181254a7Smrg __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
1424fee23f9Smrg return __init;
1434fee23f9Smrg }
1444fee23f9Smrg
1454fee23f9Smrg /**
1464fee23f9Smrg * @brief Accumulate values in a range with operation.
1474fee23f9Smrg *
148181254a7Smrg * Accumulates the values in the range `[first,last)` using the function
149181254a7Smrg * object `__binary_op`. The initial value is `__init`. The values are
1504fee23f9Smrg * processed in order.
1514fee23f9Smrg *
15248fb7bfaSmrg * @param __first Start of range.
15348fb7bfaSmrg * @param __last End of range.
15448fb7bfaSmrg * @param __init Starting value to add other values to.
15548fb7bfaSmrg * @param __binary_op Function object to accumulate with.
1564fee23f9Smrg * @return The final sum.
1574fee23f9Smrg */
1584fee23f9Smrg template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
159fb8a8121Smrg _GLIBCXX20_CONSTEXPR
1604fee23f9Smrg inline _Tp
1614fee23f9Smrg accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
1624fee23f9Smrg _BinaryOperation __binary_op)
1634fee23f9Smrg {
1644fee23f9Smrg // concept requirements
1654fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
1664fee23f9Smrg __glibcxx_requires_valid_range(__first, __last);
1674fee23f9Smrg
1684fee23f9Smrg for (; __first != __last; ++__first)
169181254a7Smrg __init = __binary_op(_GLIBCXX_MOVE_IF_20(__init), *__first);
1704fee23f9Smrg return __init;
1714fee23f9Smrg }
1724fee23f9Smrg
1734fee23f9Smrg /**
1744fee23f9Smrg * @brief Compute inner product of two ranges.
1754fee23f9Smrg *
17648fb7bfaSmrg * Starting with an initial value of @p __init, multiplies successive
1774fee23f9Smrg * elements from the two ranges and adds each product into the accumulated
1784fee23f9Smrg * value using operator+(). The values in the ranges are processed in
1794fee23f9Smrg * order.
1804fee23f9Smrg *
18148fb7bfaSmrg * @param __first1 Start of range 1.
18248fb7bfaSmrg * @param __last1 End of range 1.
18348fb7bfaSmrg * @param __first2 Start of range 2.
18448fb7bfaSmrg * @param __init Starting value to add other values to.
1854fee23f9Smrg * @return The final inner product.
1864fee23f9Smrg */
1874fee23f9Smrg template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
188fb8a8121Smrg _GLIBCXX20_CONSTEXPR
1894fee23f9Smrg inline _Tp
1904fee23f9Smrg inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
1914fee23f9Smrg _InputIterator2 __first2, _Tp __init)
1924fee23f9Smrg {
1934fee23f9Smrg // concept requirements
1944fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
1954fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
1964fee23f9Smrg __glibcxx_requires_valid_range(__first1, __last1);
1974fee23f9Smrg
198f9a78e0eSmrg for (; __first1 != __last1; ++__first1, (void)++__first2)
199181254a7Smrg __init = _GLIBCXX_MOVE_IF_20(__init) + (*__first1 * *__first2);
2004fee23f9Smrg return __init;
2014fee23f9Smrg }
2024fee23f9Smrg
2034fee23f9Smrg /**
2044fee23f9Smrg * @brief Compute inner product of two ranges.
2054fee23f9Smrg *
20648fb7bfaSmrg * Starting with an initial value of @p __init, applies @p __binary_op2 to
2074fee23f9Smrg * successive elements from the two ranges and accumulates each result into
20848fb7bfaSmrg * the accumulated value using @p __binary_op1. The values in the ranges are
2094fee23f9Smrg * processed in order.
2104fee23f9Smrg *
21148fb7bfaSmrg * @param __first1 Start of range 1.
21248fb7bfaSmrg * @param __last1 End of range 1.
21348fb7bfaSmrg * @param __first2 Start of range 2.
21448fb7bfaSmrg * @param __init Starting value to add other values to.
21548fb7bfaSmrg * @param __binary_op1 Function object to accumulate with.
21648fb7bfaSmrg * @param __binary_op2 Function object to apply to pairs of input values.
2174fee23f9Smrg * @return The final inner product.
2184fee23f9Smrg */
2194fee23f9Smrg template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
2204fee23f9Smrg typename _BinaryOperation1, typename _BinaryOperation2>
221fb8a8121Smrg _GLIBCXX20_CONSTEXPR
2224fee23f9Smrg inline _Tp
2234fee23f9Smrg inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
2244fee23f9Smrg _InputIterator2 __first2, _Tp __init,
2254fee23f9Smrg _BinaryOperation1 __binary_op1,
2264fee23f9Smrg _BinaryOperation2 __binary_op2)
2274fee23f9Smrg {
2284fee23f9Smrg // concept requirements
2294fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
2304fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
2314fee23f9Smrg __glibcxx_requires_valid_range(__first1, __last1);
2324fee23f9Smrg
233f9a78e0eSmrg for (; __first1 != __last1; ++__first1, (void)++__first2)
234181254a7Smrg __init = __binary_op1(_GLIBCXX_MOVE_IF_20(__init),
235181254a7Smrg __binary_op2(*__first1, *__first2));
2364fee23f9Smrg return __init;
2374fee23f9Smrg }
2384fee23f9Smrg
2394fee23f9Smrg /**
2404fee23f9Smrg * @brief Return list of partial sums
2414fee23f9Smrg *
24248fb7bfaSmrg * Accumulates the values in the range [first,last) using the @c + operator.
2434fee23f9Smrg * As each successive input value is added into the total, that partial sum
24448fb7bfaSmrg * is written to @p __result. Therefore, the first value in @p __result is
24548fb7bfaSmrg * the first value of the input, the second value in @p __result is the sum
24648fb7bfaSmrg * of the first and second input values, and so on.
2474fee23f9Smrg *
24848fb7bfaSmrg * @param __first Start of input range.
24948fb7bfaSmrg * @param __last End of input range.
25048fb7bfaSmrg * @param __result Output sum.
25148fb7bfaSmrg * @return Iterator pointing just beyond the values written to __result.
2524fee23f9Smrg */
2534fee23f9Smrg template<typename _InputIterator, typename _OutputIterator>
254fb8a8121Smrg _GLIBCXX20_CONSTEXPR
2554fee23f9Smrg _OutputIterator
2564fee23f9Smrg partial_sum(_InputIterator __first, _InputIterator __last,
2574fee23f9Smrg _OutputIterator __result)
2584fee23f9Smrg {
2594fee23f9Smrg typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
2604fee23f9Smrg
2614fee23f9Smrg // concept requirements
2624fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
2634fee23f9Smrg __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
2644fee23f9Smrg _ValueType>)
2654fee23f9Smrg __glibcxx_requires_valid_range(__first, __last);
2664fee23f9Smrg
2674fee23f9Smrg if (__first == __last)
2684fee23f9Smrg return __result;
2694fee23f9Smrg _ValueType __value = *__first;
2704fee23f9Smrg *__result = __value;
2714fee23f9Smrg while (++__first != __last)
2724fee23f9Smrg {
273181254a7Smrg __value = _GLIBCXX_MOVE_IF_20(__value) + *__first;
2744fee23f9Smrg *++__result = __value;
2754fee23f9Smrg }
2764fee23f9Smrg return ++__result;
2774fee23f9Smrg }
2784fee23f9Smrg
2794fee23f9Smrg /**
2804fee23f9Smrg * @brief Return list of partial sums
2814fee23f9Smrg *
28248fb7bfaSmrg * Accumulates the values in the range [first,last) using @p __binary_op.
2834fee23f9Smrg * As each successive input value is added into the total, that partial sum
28448fb7bfaSmrg * is written to @p __result. Therefore, the first value in @p __result is
28548fb7bfaSmrg * the first value of the input, the second value in @p __result is the sum
28648fb7bfaSmrg * of the first and second input values, and so on.
2874fee23f9Smrg *
28848fb7bfaSmrg * @param __first Start of input range.
28948fb7bfaSmrg * @param __last End of input range.
29048fb7bfaSmrg * @param __result Output sum.
29148fb7bfaSmrg * @param __binary_op Function object.
29248fb7bfaSmrg * @return Iterator pointing just beyond the values written to __result.
2934fee23f9Smrg */
2944fee23f9Smrg template<typename _InputIterator, typename _OutputIterator,
2954fee23f9Smrg typename _BinaryOperation>
296fb8a8121Smrg _GLIBCXX20_CONSTEXPR
2974fee23f9Smrg _OutputIterator
2984fee23f9Smrg partial_sum(_InputIterator __first, _InputIterator __last,
2994fee23f9Smrg _OutputIterator __result, _BinaryOperation __binary_op)
3004fee23f9Smrg {
3014fee23f9Smrg typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
3024fee23f9Smrg
3034fee23f9Smrg // concept requirements
3044fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
3054fee23f9Smrg __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
3064fee23f9Smrg _ValueType>)
3074fee23f9Smrg __glibcxx_requires_valid_range(__first, __last);
3084fee23f9Smrg
3094fee23f9Smrg if (__first == __last)
3104fee23f9Smrg return __result;
3114fee23f9Smrg _ValueType __value = *__first;
3124fee23f9Smrg *__result = __value;
3134fee23f9Smrg while (++__first != __last)
3144fee23f9Smrg {
315181254a7Smrg __value = __binary_op(_GLIBCXX_MOVE_IF_20(__value), *__first);
3164fee23f9Smrg *++__result = __value;
3174fee23f9Smrg }
3184fee23f9Smrg return ++__result;
3194fee23f9Smrg }
3204fee23f9Smrg
3214fee23f9Smrg /**
3224fee23f9Smrg * @brief Return differences between adjacent values.
3234fee23f9Smrg *
3244fee23f9Smrg * Computes the difference between adjacent values in the range
32548fb7bfaSmrg * [first,last) using operator-() and writes the result to @p __result.
3264fee23f9Smrg *
32748fb7bfaSmrg * @param __first Start of input range.
32848fb7bfaSmrg * @param __last End of input range.
32948fb7bfaSmrg * @param __result Output sums.
3304fee23f9Smrg * @return Iterator pointing just beyond the values written to result.
3314fee23f9Smrg */
332*0a307195Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
333*0a307195Smrg // DR 539. partial_sum and adjacent_difference should mention requirements
3344fee23f9Smrg template<typename _InputIterator, typename _OutputIterator>
335fb8a8121Smrg _GLIBCXX20_CONSTEXPR
3364fee23f9Smrg _OutputIterator
3374fee23f9Smrg adjacent_difference(_InputIterator __first,
3384fee23f9Smrg _InputIterator __last, _OutputIterator __result)
3394fee23f9Smrg {
3404fee23f9Smrg typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
3414fee23f9Smrg
3424fee23f9Smrg // concept requirements
3434fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
3444fee23f9Smrg __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
3454fee23f9Smrg _ValueType>)
3464fee23f9Smrg __glibcxx_requires_valid_range(__first, __last);
3474fee23f9Smrg
3484fee23f9Smrg if (__first == __last)
3494fee23f9Smrg return __result;
3504fee23f9Smrg _ValueType __value = *__first;
3514fee23f9Smrg *__result = __value;
3524fee23f9Smrg while (++__first != __last)
3534fee23f9Smrg {
3544fee23f9Smrg _ValueType __tmp = *__first;
355181254a7Smrg *++__result = __tmp - _GLIBCXX_MOVE_IF_20(__value);
3564fee23f9Smrg __value = _GLIBCXX_MOVE(__tmp);
3574fee23f9Smrg }
3584fee23f9Smrg return ++__result;
3594fee23f9Smrg }
3604fee23f9Smrg
3614fee23f9Smrg /**
3624fee23f9Smrg * @brief Return differences between adjacent values.
3634fee23f9Smrg *
3644fee23f9Smrg * Computes the difference between adjacent values in the range
36548fb7bfaSmrg * [__first,__last) using the function object @p __binary_op and writes the
36648fb7bfaSmrg * result to @p __result.
3674fee23f9Smrg *
36848fb7bfaSmrg * @param __first Start of input range.
36948fb7bfaSmrg * @param __last End of input range.
37048fb7bfaSmrg * @param __result Output sum.
37148fb7bfaSmrg * @param __binary_op Function object.
3724fee23f9Smrg * @return Iterator pointing just beyond the values written to result.
3734fee23f9Smrg */
374*0a307195Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
375*0a307195Smrg // DR 539. partial_sum and adjacent_difference should mention requirements
3764fee23f9Smrg template<typename _InputIterator, typename _OutputIterator,
3774fee23f9Smrg typename _BinaryOperation>
378fb8a8121Smrg _GLIBCXX20_CONSTEXPR
3794fee23f9Smrg _OutputIterator
3804fee23f9Smrg adjacent_difference(_InputIterator __first, _InputIterator __last,
3814fee23f9Smrg _OutputIterator __result, _BinaryOperation __binary_op)
3824fee23f9Smrg {
3834fee23f9Smrg typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
3844fee23f9Smrg
3854fee23f9Smrg // concept requirements
3864fee23f9Smrg __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
3874fee23f9Smrg __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
3884fee23f9Smrg _ValueType>)
3894fee23f9Smrg __glibcxx_requires_valid_range(__first, __last);
3904fee23f9Smrg
3914fee23f9Smrg if (__first == __last)
3924fee23f9Smrg return __result;
3934fee23f9Smrg _ValueType __value = *__first;
3944fee23f9Smrg *__result = __value;
3954fee23f9Smrg while (++__first != __last)
3964fee23f9Smrg {
3974fee23f9Smrg _ValueType __tmp = *__first;
398181254a7Smrg *++__result = __binary_op(__tmp, _GLIBCXX_MOVE_IF_20(__value));
3994fee23f9Smrg __value = _GLIBCXX_MOVE(__tmp);
4004fee23f9Smrg }
4014fee23f9Smrg return ++__result;
4024fee23f9Smrg }
4034fee23f9Smrg
404a448f87cSmrg /// @} group numeric_ops
405181254a7Smrg
406181254a7Smrg #undef _GLIBCXX_MOVE_IF_20
407181254a7Smrg
40848fb7bfaSmrg _GLIBCXX_END_NAMESPACE_ALGO
40948fb7bfaSmrg } // namespace std
4104fee23f9Smrg
4114fee23f9Smrg #endif /* _STL_NUMERIC_H */
412