| 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 |  | 
| 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 |  |