1 // Numeric functions implementation -*- C++ -*-
2 
3 // Copyright (C) 2001-2021 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 
_GLIBCXX_VISIBILITY(default)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    *  @return  Nothing.
83    *  @ingroup numeric_ops
84    */
85   template<typename _ForwardIterator, typename _Tp>
86     _GLIBCXX20_CONSTEXPR
87     void
88     iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
89     {
90       // concept requirements
91       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
92 				  _ForwardIterator>)
93       __glibcxx_function_requires(_ConvertibleConcept<_Tp,
94 	    typename iterator_traits<_ForwardIterator>::value_type>)
95       __glibcxx_requires_valid_range(__first, __last);
96 
97       for (; __first != __last; ++__first)
98 	{
99 	  *__first = __value;
100 	  ++__value;
101 	}
102     }
103 #endif
104 
105 _GLIBCXX_END_NAMESPACE_VERSION
106 
107 _GLIBCXX_BEGIN_NAMESPACE_ALGO
108 
109 #if __cplusplus > 201703L
110 // _GLIBCXX_RESOLVE_LIB_DEFECTS
111 // DR 2055. std::move in std::accumulate and other algorithms
112 # define _GLIBCXX_MOVE_IF_20(_E) std::move(_E)
113 #else
114 # define _GLIBCXX_MOVE_IF_20(_E) _E
115 #endif
116 
117   /// @addtogroup numeric_ops
118   /// @{
119 
120   /**
121    *  @brief  Accumulate values in a range.
122    *
123    *  Accumulates the values in the range [first,last) using operator+().  The
124    *  initial value is @a init.  The values are processed in order.
125    *
126    *  @param  __first  Start of range.
127    *  @param  __last  End of range.
128    *  @param  __init  Starting value to add other values to.
129    *  @return  The final sum.
130    */
131   template<typename _InputIterator, typename _Tp>
132     _GLIBCXX20_CONSTEXPR
133     inline _Tp
134     accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
135     {
136       // concept requirements
137       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
138       __glibcxx_requires_valid_range(__first, __last);
139 
140       for (; __first != __last; ++__first)
141 	__init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
142       return __init;
143     }
144 
145   /**
146    *  @brief  Accumulate values in a range with operation.
147    *
148    *  Accumulates the values in the range `[first,last)` using the function
149    *  object `__binary_op`.  The initial value is `__init`.  The values are
150    *  processed in order.
151    *
152    *  @param  __first  Start of range.
153    *  @param  __last  End of range.
154    *  @param  __init  Starting value to add other values to.
155    *  @param  __binary_op  Function object to accumulate with.
156    *  @return  The final sum.
157    */
158   template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
159     _GLIBCXX20_CONSTEXPR
160     inline _Tp
161     accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
162 	       _BinaryOperation __binary_op)
163     {
164       // concept requirements
165       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
166       __glibcxx_requires_valid_range(__first, __last);
167 
168       for (; __first != __last; ++__first)
169 	__init = __binary_op(_GLIBCXX_MOVE_IF_20(__init), *__first);
170       return __init;
171     }
172 
173   /**
174    *  @brief  Compute inner product of two ranges.
175    *
176    *  Starting with an initial value of @p __init, multiplies successive
177    *  elements from the two ranges and adds each product into the accumulated
178    *  value using operator+().  The values in the ranges are processed in
179    *  order.
180    *
181    *  @param  __first1  Start of range 1.
182    *  @param  __last1  End of range 1.
183    *  @param  __first2  Start of range 2.
184    *  @param  __init  Starting value to add other values to.
185    *  @return  The final inner product.
186    */
187   template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
188     _GLIBCXX20_CONSTEXPR
189     inline _Tp
190     inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
191 		  _InputIterator2 __first2, _Tp __init)
192     {
193       // concept requirements
194       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
195       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
196       __glibcxx_requires_valid_range(__first1, __last1);
197 
198       for (; __first1 != __last1; ++__first1, (void)++__first2)
199 	__init = _GLIBCXX_MOVE_IF_20(__init) + (*__first1 * *__first2);
200       return __init;
201     }
202 
203   /**
204    *  @brief  Compute inner product of two ranges.
205    *
206    *  Starting with an initial value of @p __init, applies @p __binary_op2 to
207    *  successive elements from the two ranges and accumulates each result into
208    *  the accumulated value using @p __binary_op1.  The values in the ranges are
209    *  processed in order.
210    *
211    *  @param  __first1  Start of range 1.
212    *  @param  __last1  End of range 1.
213    *  @param  __first2  Start of range 2.
214    *  @param  __init  Starting value to add other values to.
215    *  @param  __binary_op1  Function object to accumulate with.
216    *  @param  __binary_op2  Function object to apply to pairs of input values.
217    *  @return  The final inner product.
218    */
219   template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
220 	   typename _BinaryOperation1, typename _BinaryOperation2>
221     _GLIBCXX20_CONSTEXPR
222     inline _Tp
223     inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
224 		  _InputIterator2 __first2, _Tp __init,
225 		  _BinaryOperation1 __binary_op1,
226 		  _BinaryOperation2 __binary_op2)
227     {
228       // concept requirements
229       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
230       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
231       __glibcxx_requires_valid_range(__first1, __last1);
232 
233       for (; __first1 != __last1; ++__first1, (void)++__first2)
234 	__init = __binary_op1(_GLIBCXX_MOVE_IF_20(__init),
235 			      __binary_op2(*__first1, *__first2));
236       return __init;
237     }
238 
239   /**
240    *  @brief  Return list of partial sums
241    *
242    *  Accumulates the values in the range [first,last) using the @c + operator.
243    *  As each successive input value is added into the total, that partial sum
244    *  is written to @p __result.  Therefore, the first value in @p __result is
245    *  the first value of the input, the second value in @p __result is the sum
246    *  of the first and second input values, and so on.
247    *
248    *  @param  __first  Start of input range.
249    *  @param  __last  End of input range.
250    *  @param  __result  Output sum.
251    *  @return  Iterator pointing just beyond the values written to __result.
252    */
253   template<typename _InputIterator, typename _OutputIterator>
254     _GLIBCXX20_CONSTEXPR
255     _OutputIterator
256     partial_sum(_InputIterator __first, _InputIterator __last,
257 		_OutputIterator __result)
258     {
259       typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
260 
261       // concept requirements
262       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
263       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
264 				                         _ValueType>)
265       __glibcxx_requires_valid_range(__first, __last);
266 
267       if (__first == __last)
268 	return __result;
269       _ValueType __value = *__first;
270       *__result = __value;
271       while (++__first != __last)
272 	{
273 	  __value = _GLIBCXX_MOVE_IF_20(__value) + *__first;
274 	  *++__result = __value;
275 	}
276       return ++__result;
277     }
278 
279   /**
280    *  @brief  Return list of partial sums
281    *
282    *  Accumulates the values in the range [first,last) using @p __binary_op.
283    *  As each successive input value is added into the total, that partial sum
284    *  is written to @p __result.  Therefore, the first value in @p __result is
285    *  the first value of the input, the second value in @p __result is the sum
286    *  of the first and second input values, and so on.
287    *
288    *  @param  __first  Start of input range.
289    *  @param  __last  End of input range.
290    *  @param  __result  Output sum.
291    *  @param  __binary_op  Function object.
292    *  @return  Iterator pointing just beyond the values written to __result.
293    */
294   template<typename _InputIterator, typename _OutputIterator,
295 	   typename _BinaryOperation>
296     _GLIBCXX20_CONSTEXPR
297     _OutputIterator
298     partial_sum(_InputIterator __first, _InputIterator __last,
299 		_OutputIterator __result, _BinaryOperation __binary_op)
300     {
301       typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
302 
303       // concept requirements
304       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
305       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
306 				                         _ValueType>)
307       __glibcxx_requires_valid_range(__first, __last);
308 
309       if (__first == __last)
310 	return __result;
311       _ValueType __value = *__first;
312       *__result = __value;
313       while (++__first != __last)
314 	{
315 	  __value = __binary_op(_GLIBCXX_MOVE_IF_20(__value), *__first);
316 	  *++__result = __value;
317 	}
318       return ++__result;
319     }
320 
321   /**
322    *  @brief  Return differences between adjacent values.
323    *
324    *  Computes the difference between adjacent values in the range
325    *  [first,last) using operator-() and writes the result to @p __result.
326    *
327    *  @param  __first  Start of input range.
328    *  @param  __last  End of input range.
329    *  @param  __result  Output sums.
330    *  @return  Iterator pointing just beyond the values written to result.
331    *
332    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
333    *  DR 539. partial_sum and adjacent_difference should mention requirements
334    */
335   template<typename _InputIterator, typename _OutputIterator>
336     _GLIBCXX20_CONSTEXPR
337     _OutputIterator
338     adjacent_difference(_InputIterator __first,
339 			_InputIterator __last, _OutputIterator __result)
340     {
341       typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
342 
343       // concept requirements
344       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
345       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
346 				                         _ValueType>)
347       __glibcxx_requires_valid_range(__first, __last);
348 
349       if (__first == __last)
350 	return __result;
351       _ValueType __value = *__first;
352       *__result = __value;
353       while (++__first != __last)
354 	{
355 	  _ValueType __tmp = *__first;
356 	  *++__result = __tmp - _GLIBCXX_MOVE_IF_20(__value);
357 	  __value = _GLIBCXX_MOVE(__tmp);
358 	}
359       return ++__result;
360     }
361 
362   /**
363    *  @brief  Return differences between adjacent values.
364    *
365    *  Computes the difference between adjacent values in the range
366    *  [__first,__last) using the function object @p __binary_op and writes the
367    *  result to @p __result.
368    *
369    *  @param  __first  Start of input range.
370    *  @param  __last  End of input range.
371    *  @param  __result  Output sum.
372    *  @param  __binary_op Function object.
373    *  @return  Iterator pointing just beyond the values written to result.
374    *
375    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
376    *  DR 539. partial_sum and adjacent_difference should mention requirements
377    */
378   template<typename _InputIterator, typename _OutputIterator,
379 	   typename _BinaryOperation>
380     _GLIBCXX20_CONSTEXPR
381     _OutputIterator
382     adjacent_difference(_InputIterator __first, _InputIterator __last,
383 			_OutputIterator __result, _BinaryOperation __binary_op)
384     {
385       typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
386 
387       // concept requirements
388       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
389       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
390 				                         _ValueType>)
391       __glibcxx_requires_valid_range(__first, __last);
392 
393       if (__first == __last)
394 	return __result;
395       _ValueType __value = *__first;
396       *__result = __value;
397       while (++__first != __last)
398 	{
399 	  _ValueType __tmp = *__first;
400 	  *++__result = __binary_op(__tmp, _GLIBCXX_MOVE_IF_20(__value));
401 	  __value = _GLIBCXX_MOVE(__tmp);
402 	}
403       return ++__result;
404     }
405 
406   /// @} group numeric_ops
407 
408 #undef _GLIBCXX_MOVE_IF_20
409 
410 _GLIBCXX_END_NAMESPACE_ALGO
411 } // namespace std
412 
413 #endif /* _STL_NUMERIC_H */
414