libstdc++
stl_numeric.h
Go to the documentation of this file.
1 // Numeric functions implementation -*- C++ -*-
2 
3 // Copyright (C) 2001-2026 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /*
26  *
27  * Copyright (c) 1994
28  * Hewlett-Packard Company
29  *
30  * Permission to use, copy, modify, distribute and sell this software
31  * and its documentation for any purpose is hereby granted without fee,
32  * provided that the above copyright notice appear in all copies and
33  * that both that copyright notice and this permission notice appear
34  * in supporting documentation. Hewlett-Packard Company makes no
35  * representations about the suitability of this software for any
36  * purpose. It is provided "as is" without express or implied warranty.
37  *
38  *
39  * Copyright (c) 1996,1997
40  * Silicon Graphics Computer Systems, Inc.
41  *
42  * Permission to use, copy, modify, distribute and sell this software
43  * and its documentation for any purpose is hereby granted without fee,
44  * provided that the above copyright notice appear in all copies and
45  * that both that copyright notice and this permission notice appear
46  * in supporting documentation. Silicon Graphics makes no
47  * representations about the suitability of this software for any
48  * purpose. It is provided "as is" without express or implied warranty.
49  */
50 
51 /** @file bits/stl_numeric.h
52  * This is an internal header file, included by other library headers.
53  * Do not attempt to use it directly. @headername{numeric}
54  */
55 
56 #ifndef _STL_NUMERIC_H
57 #define _STL_NUMERIC_H 1
58 
59 #include <bits/concept_check.h>
60 #include <debug/debug.h>
61 #include <bits/move.h> // For _GLIBCXX_MOVE
62 
63 
64 namespace std _GLIBCXX_VISIBILITY(default)
65 {
66 _GLIBCXX_BEGIN_NAMESPACE_VERSION
67 
68  /** @defgroup numeric_ops Generalized Numeric operations
69  * @ingroup algorithms
70  */
71 
72 #if __cplusplus >= 201103L
73  /**
74  * @brief Create a range of sequentially increasing values.
75  *
76  * For each element in the range @p [first,last) assigns @p value and
77  * increments @p value as if by @p ++value.
78  *
79  * @param __first Start of range.
80  * @param __last End of range.
81  * @param __value Starting value.
82  * @ingroup numeric_ops
83  */
84  template<typename _ForwardIterator, typename _Tp>
85  _GLIBCXX20_CONSTEXPR
86  void
87  iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
88  {
89  // concept requirements
90  __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
91  _ForwardIterator>)
92  __glibcxx_function_requires(_ConvertibleConcept<_Tp,
94  __glibcxx_requires_valid_range(__first, __last);
95 
96  for (; __first != __last; ++__first)
97  {
98  *__first = __value;
99  ++__value;
100  }
101  }
102 #endif
103 
104 _GLIBCXX_END_NAMESPACE_VERSION
105 
106 _GLIBCXX_BEGIN_NAMESPACE_ALGO
107 
108 #if __cplusplus > 201703L
109 // _GLIBCXX_RESOLVE_LIB_DEFECTS
110 // DR 2055. std::move in std::accumulate and other algorithms
111 # define _GLIBCXX_MOVE_IF_20(_E) std::move(_E)
112 #else
113 # define _GLIBCXX_MOVE_IF_20(_E) _E
114 #endif
115 
116  /// @addtogroup numeric_ops
117  /// @{
118 
119  /**
120  * @brief Accumulate values in a range.
121  *
122  * Accumulates the values in the range [first,last) using operator+(). The
123  * initial value is @a init. The values are processed in order.
124  *
125  * @param __first Start of range.
126  * @param __last End of range.
127  * @param __init Starting value to add other values to.
128  * @return The final sum.
129  */
130  template<typename _InputIterator, typename _Tp>
131  _GLIBCXX20_CONSTEXPR
132  inline _Tp
133  accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
134  {
135  // concept requirements
136  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
137  __glibcxx_requires_valid_range(__first, __last);
138 
139  for (; __first != __last; ++__first)
140  __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
141  return __init;
142  }
143 
144  /**
145  * @brief Accumulate values in a range with operation.
146  *
147  * Accumulates the values in the range `[first,last)` using the function
148  * object `__binary_op`. The initial value is `__init`. The values are
149  * processed in order.
150  *
151  * @param __first Start of range.
152  * @param __last End of range.
153  * @param __init Starting value to add other values to.
154  * @param __binary_op Function object to accumulate with.
155  * @return The final sum.
156  */
157  template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
158  _GLIBCXX20_CONSTEXPR
159  inline _Tp
160  accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
161  _BinaryOperation __binary_op)
162  {
163  // concept requirements
164  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
165  __glibcxx_requires_valid_range(__first, __last);
166 
167  for (; __first != __last; ++__first)
168  __init = __binary_op(_GLIBCXX_MOVE_IF_20(__init), *__first);
169  return __init;
170  }
171 
172  /**
173  * @brief Compute inner product of two ranges.
174  *
175  * Starting with an initial value of @p __init, multiplies successive
176  * elements from the two ranges and adds each product into the accumulated
177  * value using operator+(). The values in the ranges are processed in
178  * order.
179  *
180  * @param __first1 Start of range 1.
181  * @param __last1 End of range 1.
182  * @param __first2 Start of range 2.
183  * @param __init Starting value to add other values to.
184  * @return The final inner product.
185  */
186  template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
187  _GLIBCXX20_CONSTEXPR
188  inline _Tp
189  inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
190  _InputIterator2 __first2, _Tp __init)
191  {
192  // concept requirements
193  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
194  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
195  __glibcxx_requires_valid_range(__first1, __last1);
196 
197  for (; __first1 != __last1; ++__first1, (void)++__first2)
198  __init = _GLIBCXX_MOVE_IF_20(__init) + (*__first1 * *__first2);
199  return __init;
200  }
201 
202  /**
203  * @brief Compute inner product of two ranges.
204  *
205  * Starting with an initial value of @p __init, applies @p __binary_op2 to
206  * successive elements from the two ranges and accumulates each result into
207  * the accumulated value using @p __binary_op1. The values in the ranges are
208  * processed in order.
209  *
210  * @param __first1 Start of range 1.
211  * @param __last1 End of range 1.
212  * @param __first2 Start of range 2.
213  * @param __init Starting value to add other values to.
214  * @param __binary_op1 Function object to accumulate with.
215  * @param __binary_op2 Function object to apply to pairs of input values.
216  * @return The final inner product.
217  */
218  template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
219  typename _BinaryOperation1, typename _BinaryOperation2>
220  _GLIBCXX20_CONSTEXPR
221  inline _Tp
222  inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
223  _InputIterator2 __first2, _Tp __init,
224  _BinaryOperation1 __binary_op1,
225  _BinaryOperation2 __binary_op2)
226  {
227  // concept requirements
228  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
229  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
230  __glibcxx_requires_valid_range(__first1, __last1);
231 
232  for (; __first1 != __last1; ++__first1, (void)++__first2)
233  __init = __binary_op1(_GLIBCXX_MOVE_IF_20(__init),
234  __binary_op2(*__first1, *__first2));
235  return __init;
236  }
237 
238  /**
239  * @brief Return list of partial sums
240  *
241  * Accumulates the values in the range [first,last) using the @c + operator.
242  * As each successive input value is added into the total, that partial sum
243  * is written to @p __result. Therefore, the first value in @p __result is
244  * the first value of the input, the second value in @p __result is the sum
245  * of the first and second input values, and so on.
246  *
247  * @param __first Start of input range.
248  * @param __last End of input range.
249  * @param __result Output sum.
250  * @return Iterator pointing just beyond the values written to __result.
251  */
252  template<typename _InputIterator, typename _OutputIterator>
253  _GLIBCXX20_CONSTEXPR
254  _OutputIterator
255  partial_sum(_InputIterator __first, _InputIterator __last,
256  _OutputIterator __result)
257  {
258  typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
259 
260  // concept requirements
261  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
262  __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
263  _ValueType>)
264  __glibcxx_requires_valid_range(__first, __last);
265 
266  if (__first == __last)
267  return __result;
268  _ValueType __value = *__first;
269  *__result = __value;
270  while (++__first != __last)
271  {
272  __value = _GLIBCXX_MOVE_IF_20(__value) + *__first;
273  *++__result = __value;
274  }
275  return ++__result;
276  }
277 
278  /**
279  * @brief Return list of partial sums
280  *
281  * Accumulates the values in the range [first,last) using @p __binary_op.
282  * As each successive input value is added into the total, that partial sum
283  * is written to @p __result. Therefore, the first value in @p __result is
284  * the first value of the input, the second value in @p __result is the sum
285  * of the first and second input values, and so on.
286  *
287  * @param __first Start of input range.
288  * @param __last End of input range.
289  * @param __result Output sum.
290  * @param __binary_op Function object.
291  * @return Iterator pointing just beyond the values written to __result.
292  */
293  template<typename _InputIterator, typename _OutputIterator,
294  typename _BinaryOperation>
295  _GLIBCXX20_CONSTEXPR
296  _OutputIterator
297  partial_sum(_InputIterator __first, _InputIterator __last,
298  _OutputIterator __result, _BinaryOperation __binary_op)
299  {
300  typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
301 
302  // concept requirements
303  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
304  __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
305  _ValueType>)
306  __glibcxx_requires_valid_range(__first, __last);
307 
308  if (__first == __last)
309  return __result;
310  _ValueType __value = *__first;
311  *__result = __value;
312  while (++__first != __last)
313  {
314  __value = __binary_op(_GLIBCXX_MOVE_IF_20(__value), *__first);
315  *++__result = __value;
316  }
317  return ++__result;
318  }
319 
320  /**
321  * @brief Return differences between adjacent values.
322  *
323  * Computes the difference between adjacent values in the range
324  * [first,last) using operator-() and writes the result to @p __result.
325  *
326  * @param __first Start of input range.
327  * @param __last End of input range.
328  * @param __result Output sums.
329  * @return Iterator pointing just beyond the values written to result.
330  */
331  // _GLIBCXX_RESOLVE_LIB_DEFECTS
332  // DR 539. partial_sum and adjacent_difference should mention requirements
333  template<typename _InputIterator, typename _OutputIterator>
334  _GLIBCXX20_CONSTEXPR
335  _OutputIterator
336  adjacent_difference(_InputIterator __first,
337  _InputIterator __last, _OutputIterator __result)
338  {
339  typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
340 
341  // concept requirements
342  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
343  __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
344  _ValueType>)
345  __glibcxx_requires_valid_range(__first, __last);
346 
347  if (__first == __last)
348  return __result;
349  _ValueType __value = *__first;
350  *__result = __value;
351  while (++__first != __last)
352  {
353  _ValueType __tmp = *__first;
354  *++__result = __tmp - _GLIBCXX_MOVE_IF_20(__value);
355  __value = _GLIBCXX_MOVE(__tmp);
356  }
357  return ++__result;
358  }
359 
360  /**
361  * @brief Return differences between adjacent values.
362  *
363  * Computes the difference between adjacent values in the range
364  * [__first,__last) using the function object @p __binary_op and writes the
365  * result to @p __result.
366  *
367  * @param __first Start of input range.
368  * @param __last End of input range.
369  * @param __result Output sum.
370  * @param __binary_op Function object.
371  * @return Iterator pointing just beyond the values written to result.
372  */
373  // _GLIBCXX_RESOLVE_LIB_DEFECTS
374  // DR 539. partial_sum and adjacent_difference should mention requirements
375  template<typename _InputIterator, typename _OutputIterator,
376  typename _BinaryOperation>
377  _GLIBCXX20_CONSTEXPR
378  _OutputIterator
379  adjacent_difference(_InputIterator __first, _InputIterator __last,
380  _OutputIterator __result, _BinaryOperation __binary_op)
381  {
382  typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
383 
384  // concept requirements
385  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
386  __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
387  _ValueType>)
388  __glibcxx_requires_valid_range(__first, __last);
389 
390  if (__first == __last)
391  return __result;
392  _ValueType __value = *__first;
393  *__result = __value;
394  while (++__first != __last)
395  {
396  _ValueType __tmp = *__first;
397  *++__result = __binary_op(__tmp, _GLIBCXX_MOVE_IF_20(__value));
398  __value = _GLIBCXX_MOVE(__tmp);
399  }
400  return ++__result;
401  }
402 
403  /// @} group numeric_ops
404 
405 #undef _GLIBCXX_MOVE_IF_20
406 
407 _GLIBCXX_END_NAMESPACE_ALGO
408 } // namespace std
409 
410 #endif /* _STL_NUMERIC_H */
constexpr _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
Accumulate values in a range.
Definition: stl_numeric.h:133
constexpr _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
Return differences between adjacent values.
Definition: stl_numeric.h:336
constexpr void iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
Create a range of sequentially increasing values.
Definition: stl_numeric.h:87
constexpr _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
Return list of partial sums.
Definition: stl_numeric.h:255
constexpr _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
Compute inner product of two ranges.
Definition: stl_numeric.h:189
ISO C++ entities toplevel namespace is std.
Traits class for iterators.