|
libstdc++
|
00001 // Numeric functions implementation -*- C++ -*- 00002 00003 // Copyright (C) 2001-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /* 00026 * 00027 * Copyright (c) 1994 00028 * Hewlett-Packard Company 00029 * 00030 * Permission to use, copy, modify, distribute and sell this software 00031 * and its documentation for any purpose is hereby granted without fee, 00032 * provided that the above copyright notice appear in all copies and 00033 * that both that copyright notice and this permission notice appear 00034 * in supporting documentation. Hewlett-Packard Company makes no 00035 * representations about the suitability of this software for any 00036 * purpose. It is provided "as is" without express or implied warranty. 00037 * 00038 * 00039 * Copyright (c) 1996,1997 00040 * Silicon Graphics Computer Systems, Inc. 00041 * 00042 * Permission to use, copy, modify, distribute and sell this software 00043 * and its documentation for any purpose is hereby granted without fee, 00044 * provided that the above copyright notice appear in all copies and 00045 * that both that copyright notice and this permission notice appear 00046 * in supporting documentation. Silicon Graphics makes no 00047 * representations about the suitability of this software for any 00048 * purpose. It is provided "as is" without express or implied warranty. 00049 */ 00050 00051 /** @file bits/stl_numeric.h 00052 * This is an internal header file, included by other library headers. 00053 * Do not attempt to use it directly. @headername{numeric} 00054 */ 00055 00056 #ifndef _STL_NUMERIC_H 00057 #define _STL_NUMERIC_H 1 00058 00059 #include <bits/concept_check.h> 00060 #include <debug/debug.h> 00061 #include <bits/move.h> // For _GLIBCXX_MOVE 00062 00063 00064 namespace std _GLIBCXX_VISIBILITY(default) 00065 { 00066 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00067 00068 /** @defgroup numeric_ops Generalized Numeric operations 00069 * @ingroup algorithms 00070 */ 00071 00072 #if __cplusplus >= 201103L 00073 /** 00074 * @brief Create a range of sequentially increasing values. 00075 * 00076 * For each element in the range @p [first,last) assigns @p value and 00077 * increments @p value as if by @p ++value. 00078 * 00079 * @param __first Start of range. 00080 * @param __last End of range. 00081 * @param __value Starting value. 00082 * @return Nothing. 00083 * @ingroup numeric_ops 00084 */ 00085 template<typename _ForwardIterator, typename _Tp> 00086 void 00087 iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value) 00088 { 00089 // concept requirements 00090 __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 00091 _ForwardIterator>) 00092 __glibcxx_function_requires(_ConvertibleConcept<_Tp, 00093 typename iterator_traits<_ForwardIterator>::value_type>) 00094 __glibcxx_requires_valid_range(__first, __last); 00095 00096 for (; __first != __last; ++__first) 00097 { 00098 *__first = __value; 00099 ++__value; 00100 } 00101 } 00102 #endif 00103 00104 _GLIBCXX_END_NAMESPACE_VERSION 00105 00106 _GLIBCXX_BEGIN_NAMESPACE_ALGO 00107 00108 #if __cplusplus > 201703L 00109 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00110 // DR 2055. std::move in std::accumulate and other algorithms 00111 # define _GLIBCXX_MOVE_IF_20(_E) std::move(_E) 00112 #else 00113 # define _GLIBCXX_MOVE_IF_20(_E) _E 00114 #endif 00115 00116 /// @addtogroup numeric_ops 00117 /// @{ 00118 00119 /** 00120 * @brief Accumulate values in a range. 00121 * 00122 * Accumulates the values in the range [first,last) using operator+(). The 00123 * initial value is @a init. The values are processed in order. 00124 * 00125 * @param __first Start of range. 00126 * @param __last End of range. 00127 * @param __init Starting value to add other values to. 00128 * @return The final sum. 00129 */ 00130 template<typename _InputIterator, typename _Tp> 00131 inline _Tp 00132 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) 00133 { 00134 // concept requirements 00135 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 00136 __glibcxx_requires_valid_range(__first, __last); 00137 00138 for (; __first != __last; ++__first) 00139 __init = _GLIBCXX_MOVE_IF_20(__init) + *__first; 00140 return __init; 00141 } 00142 00143 /** 00144 * @brief Accumulate values in a range with operation. 00145 * 00146 * Accumulates the values in the range `[first,last)` using the function 00147 * object `__binary_op`. The initial value is `__init`. The values are 00148 * processed in order. 00149 * 00150 * @param __first Start of range. 00151 * @param __last End of range. 00152 * @param __init Starting value to add other values to. 00153 * @param __binary_op Function object to accumulate with. 00154 * @return The final sum. 00155 */ 00156 template<typename _InputIterator, typename _Tp, typename _BinaryOperation> 00157 inline _Tp 00158 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, 00159 _BinaryOperation __binary_op) 00160 { 00161 // concept requirements 00162 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 00163 __glibcxx_requires_valid_range(__first, __last); 00164 00165 for (; __first != __last; ++__first) 00166 __init = __binary_op(_GLIBCXX_MOVE_IF_20(__init), *__first); 00167 return __init; 00168 } 00169 00170 /** 00171 * @brief Compute inner product of two ranges. 00172 * 00173 * Starting with an initial value of @p __init, multiplies successive 00174 * elements from the two ranges and adds each product into the accumulated 00175 * value using operator+(). The values in the ranges are processed in 00176 * order. 00177 * 00178 * @param __first1 Start of range 1. 00179 * @param __last1 End of range 1. 00180 * @param __first2 Start of range 2. 00181 * @param __init Starting value to add other values to. 00182 * @return The final inner product. 00183 */ 00184 template<typename _InputIterator1, typename _InputIterator2, typename _Tp> 00185 inline _Tp 00186 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, 00187 _InputIterator2 __first2, _Tp __init) 00188 { 00189 // concept requirements 00190 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 00191 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 00192 __glibcxx_requires_valid_range(__first1, __last1); 00193 00194 for (; __first1 != __last1; ++__first1, (void)++__first2) 00195 __init = _GLIBCXX_MOVE_IF_20(__init) + (*__first1 * *__first2); 00196 return __init; 00197 } 00198 00199 /** 00200 * @brief Compute inner product of two ranges. 00201 * 00202 * Starting with an initial value of @p __init, applies @p __binary_op2 to 00203 * successive elements from the two ranges and accumulates each result into 00204 * the accumulated value using @p __binary_op1. The values in the ranges are 00205 * processed in order. 00206 * 00207 * @param __first1 Start of range 1. 00208 * @param __last1 End of range 1. 00209 * @param __first2 Start of range 2. 00210 * @param __init Starting value to add other values to. 00211 * @param __binary_op1 Function object to accumulate with. 00212 * @param __binary_op2 Function object to apply to pairs of input values. 00213 * @return The final inner product. 00214 */ 00215 template<typename _InputIterator1, typename _InputIterator2, typename _Tp, 00216 typename _BinaryOperation1, typename _BinaryOperation2> 00217 inline _Tp 00218 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, 00219 _InputIterator2 __first2, _Tp __init, 00220 _BinaryOperation1 __binary_op1, 00221 _BinaryOperation2 __binary_op2) 00222 { 00223 // concept requirements 00224 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 00225 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 00226 __glibcxx_requires_valid_range(__first1, __last1); 00227 00228 for (; __first1 != __last1; ++__first1, (void)++__first2) 00229 __init = __binary_op1(_GLIBCXX_MOVE_IF_20(__init), 00230 __binary_op2(*__first1, *__first2)); 00231 return __init; 00232 } 00233 00234 /** 00235 * @brief Return list of partial sums 00236 * 00237 * Accumulates the values in the range [first,last) using the @c + operator. 00238 * As each successive input value is added into the total, that partial sum 00239 * is written to @p __result. Therefore, the first value in @p __result is 00240 * the first value of the input, the second value in @p __result is the sum 00241 * of the first and second input values, and so on. 00242 * 00243 * @param __first Start of input range. 00244 * @param __last End of input range. 00245 * @param __result Output sum. 00246 * @return Iterator pointing just beyond the values written to __result. 00247 */ 00248 template<typename _InputIterator, typename _OutputIterator> 00249 _OutputIterator 00250 partial_sum(_InputIterator __first, _InputIterator __last, 00251 _OutputIterator __result) 00252 { 00253 typedef typename iterator_traits<_InputIterator>::value_type _ValueType; 00254 00255 // concept requirements 00256 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 00257 __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 00258 _ValueType>) 00259 __glibcxx_requires_valid_range(__first, __last); 00260 00261 if (__first == __last) 00262 return __result; 00263 _ValueType __value = *__first; 00264 *__result = __value; 00265 while (++__first != __last) 00266 { 00267 __value = _GLIBCXX_MOVE_IF_20(__value) + *__first; 00268 *++__result = __value; 00269 } 00270 return ++__result; 00271 } 00272 00273 /** 00274 * @brief Return list of partial sums 00275 * 00276 * Accumulates the values in the range [first,last) using @p __binary_op. 00277 * As each successive input value is added into the total, that partial sum 00278 * is written to @p __result. Therefore, the first value in @p __result is 00279 * the first value of the input, the second value in @p __result is the sum 00280 * of the first and second input values, and so on. 00281 * 00282 * @param __first Start of input range. 00283 * @param __last End of input range. 00284 * @param __result Output sum. 00285 * @param __binary_op Function object. 00286 * @return Iterator pointing just beyond the values written to __result. 00287 */ 00288 template<typename _InputIterator, typename _OutputIterator, 00289 typename _BinaryOperation> 00290 _OutputIterator 00291 partial_sum(_InputIterator __first, _InputIterator __last, 00292 _OutputIterator __result, _BinaryOperation __binary_op) 00293 { 00294 typedef typename iterator_traits<_InputIterator>::value_type _ValueType; 00295 00296 // concept requirements 00297 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 00298 __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 00299 _ValueType>) 00300 __glibcxx_requires_valid_range(__first, __last); 00301 00302 if (__first == __last) 00303 return __result; 00304 _ValueType __value = *__first; 00305 *__result = __value; 00306 while (++__first != __last) 00307 { 00308 __value = __binary_op(_GLIBCXX_MOVE_IF_20(__value), *__first); 00309 *++__result = __value; 00310 } 00311 return ++__result; 00312 } 00313 00314 /** 00315 * @brief Return differences between adjacent values. 00316 * 00317 * Computes the difference between adjacent values in the range 00318 * [first,last) using operator-() and writes the result to @p __result. 00319 * 00320 * @param __first Start of input range. 00321 * @param __last End of input range. 00322 * @param __result Output sums. 00323 * @return Iterator pointing just beyond the values written to result. 00324 * 00325 * _GLIBCXX_RESOLVE_LIB_DEFECTS 00326 * DR 539. partial_sum and adjacent_difference should mention requirements 00327 */ 00328 template<typename _InputIterator, typename _OutputIterator> 00329 _OutputIterator 00330 adjacent_difference(_InputIterator __first, 00331 _InputIterator __last, _OutputIterator __result) 00332 { 00333 typedef typename iterator_traits<_InputIterator>::value_type _ValueType; 00334 00335 // concept requirements 00336 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 00337 __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 00338 _ValueType>) 00339 __glibcxx_requires_valid_range(__first, __last); 00340 00341 if (__first == __last) 00342 return __result; 00343 _ValueType __value = *__first; 00344 *__result = __value; 00345 while (++__first != __last) 00346 { 00347 _ValueType __tmp = *__first; 00348 *++__result = __tmp - _GLIBCXX_MOVE_IF_20(__value); 00349 __value = _GLIBCXX_MOVE(__tmp); 00350 } 00351 return ++__result; 00352 } 00353 00354 /** 00355 * @brief Return differences between adjacent values. 00356 * 00357 * Computes the difference between adjacent values in the range 00358 * [__first,__last) using the function object @p __binary_op and writes the 00359 * result to @p __result. 00360 * 00361 * @param __first Start of input range. 00362 * @param __last End of input range. 00363 * @param __result Output sum. 00364 * @param __binary_op Function object. 00365 * @return Iterator pointing just beyond the values written to result. 00366 * 00367 * _GLIBCXX_RESOLVE_LIB_DEFECTS 00368 * DR 539. partial_sum and adjacent_difference should mention requirements 00369 */ 00370 template<typename _InputIterator, typename _OutputIterator, 00371 typename _BinaryOperation> 00372 _OutputIterator 00373 adjacent_difference(_InputIterator __first, _InputIterator __last, 00374 _OutputIterator __result, _BinaryOperation __binary_op) 00375 { 00376 typedef typename iterator_traits<_InputIterator>::value_type _ValueType; 00377 00378 // concept requirements 00379 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 00380 __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 00381 _ValueType>) 00382 __glibcxx_requires_valid_range(__first, __last); 00383 00384 if (__first == __last) 00385 return __result; 00386 _ValueType __value = *__first; 00387 *__result = __value; 00388 while (++__first != __last) 00389 { 00390 _ValueType __tmp = *__first; 00391 *++__result = __binary_op(__tmp, _GLIBCXX_MOVE_IF_20(__value)); 00392 __value = _GLIBCXX_MOVE(__tmp); 00393 } 00394 return ++__result; 00395 } 00396 00397 // @} group numeric_ops 00398 00399 #undef _GLIBCXX_MOVE_IF_20 00400 00401 _GLIBCXX_END_NAMESPACE_ALGO 00402 } // namespace std 00403 00404 #endif /* _STL_NUMERIC_H */