libstdc++: stl_numeric.h Source File

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
64namespace 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,
93 typename iterator_traits<_ForwardIterator>::value_type>)
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 */
concept_check.h
move.h
debug.h
std::accumulate
constexpr _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
Accumulate values in a range.
Definition stl_numeric.h:133
std::adjacent_difference
constexpr _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
Return differences between adjacent values.
Definition stl_numeric.h:336
std::iota
constexpr void iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
Create a range of sequentially increasing values.
Definition stl_numeric.h:87
std::partial_sum
constexpr _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
Return list of partial sums.
Definition stl_numeric.h:255
std::inner_product
constexpr _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
Compute inner product of two ranges.
Definition stl_numeric.h:189
std
ISO C++ entities toplevel namespace is std.
std::iterator_traits
Traits class for iterators.
Definition stl_iterator_base_types.h:180