stl_numeric.h 14 KB

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