stl_numeric.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. // Numeric functions implementation -*- C++ -*-
  2. // Copyright (C) 2001-2018 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. #if __cplusplus >= 201103L
  55. namespace std _GLIBCXX_VISIBILITY(default)
  56. {
  57. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  58. /**
  59. * @brief Create a range of sequentially increasing values.
  60. *
  61. * For each element in the range @p [first,last) assigns @p value and
  62. * increments @p value as if by @p ++value.
  63. *
  64. * @param __first Start of range.
  65. * @param __last End of range.
  66. * @param __value Starting value.
  67. * @return Nothing.
  68. */
  69. template<typename _ForwardIterator, typename _Tp>
  70. void
  71. iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
  72. {
  73. // concept requirements
  74. __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
  75. _ForwardIterator>)
  76. __glibcxx_function_requires(_ConvertibleConcept<_Tp,
  77. typename iterator_traits<_ForwardIterator>::value_type>)
  78. __glibcxx_requires_valid_range(__first, __last);
  79. for (; __first != __last; ++__first)
  80. {
  81. *__first = __value;
  82. ++__value;
  83. }
  84. }
  85. _GLIBCXX_END_NAMESPACE_VERSION
  86. } // namespace std
  87. #endif
  88. namespace std _GLIBCXX_VISIBILITY(default)
  89. {
  90. _GLIBCXX_BEGIN_NAMESPACE_ALGO
  91. /**
  92. * @brief Accumulate values in a range.
  93. *
  94. * Accumulates the values in the range [first,last) using operator+(). The
  95. * initial value is @a init. The values are processed in order.
  96. *
  97. * @param __first Start of range.
  98. * @param __last End of range.
  99. * @param __init Starting value to add other values to.
  100. * @return The final sum.
  101. */
  102. template<typename _InputIterator, typename _Tp>
  103. inline _Tp
  104. accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
  105. {
  106. // concept requirements
  107. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  108. __glibcxx_requires_valid_range(__first, __last);
  109. for (; __first != __last; ++__first)
  110. __init = __init + *__first;
  111. return __init;
  112. }
  113. /**
  114. * @brief Accumulate values in a range with operation.
  115. *
  116. * Accumulates the values in the range [first,last) using the function
  117. * object @p __binary_op. The initial value is @p __init. The values are
  118. * processed in order.
  119. *
  120. * @param __first Start of range.
  121. * @param __last End of range.
  122. * @param __init Starting value to add other values to.
  123. * @param __binary_op Function object to accumulate with.
  124. * @return The final sum.
  125. */
  126. template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
  127. inline _Tp
  128. accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
  129. _BinaryOperation __binary_op)
  130. {
  131. // concept requirements
  132. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  133. __glibcxx_requires_valid_range(__first, __last);
  134. for (; __first != __last; ++__first)
  135. __init = __binary_op(__init, *__first);
  136. return __init;
  137. }
  138. /**
  139. * @brief Compute inner product of two ranges.
  140. *
  141. * Starting with an initial value of @p __init, multiplies successive
  142. * elements from the two ranges and adds each product into the accumulated
  143. * value using operator+(). The values in the ranges are processed in
  144. * order.
  145. *
  146. * @param __first1 Start of range 1.
  147. * @param __last1 End of range 1.
  148. * @param __first2 Start of range 2.
  149. * @param __init Starting value to add other values to.
  150. * @return The final inner product.
  151. */
  152. template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
  153. inline _Tp
  154. inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
  155. _InputIterator2 __first2, _Tp __init)
  156. {
  157. // concept requirements
  158. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
  159. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
  160. __glibcxx_requires_valid_range(__first1, __last1);
  161. for (; __first1 != __last1; ++__first1, (void)++__first2)
  162. __init = __init + (*__first1 * *__first2);
  163. return __init;
  164. }
  165. /**
  166. * @brief Compute inner product of two ranges.
  167. *
  168. * Starting with an initial value of @p __init, applies @p __binary_op2 to
  169. * successive elements from the two ranges and accumulates each result into
  170. * the accumulated value using @p __binary_op1. The values in the ranges are
  171. * processed in order.
  172. *
  173. * @param __first1 Start of range 1.
  174. * @param __last1 End of range 1.
  175. * @param __first2 Start of range 2.
  176. * @param __init Starting value to add other values to.
  177. * @param __binary_op1 Function object to accumulate with.
  178. * @param __binary_op2 Function object to apply to pairs of input values.
  179. * @return The final inner product.
  180. */
  181. template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
  182. typename _BinaryOperation1, typename _BinaryOperation2>
  183. inline _Tp
  184. inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
  185. _InputIterator2 __first2, _Tp __init,
  186. _BinaryOperation1 __binary_op1,
  187. _BinaryOperation2 __binary_op2)
  188. {
  189. // concept requirements
  190. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
  191. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
  192. __glibcxx_requires_valid_range(__first1, __last1);
  193. for (; __first1 != __last1; ++__first1, (void)++__first2)
  194. __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
  195. return __init;
  196. }
  197. /**
  198. * @brief Return list of partial sums
  199. *
  200. * Accumulates the values in the range [first,last) using the @c + operator.
  201. * As each successive input value is added into the total, that partial sum
  202. * is written to @p __result. Therefore, the first value in @p __result is
  203. * the first value of the input, the second value in @p __result is the sum
  204. * of the first and second input values, and so on.
  205. *
  206. * @param __first Start of input range.
  207. * @param __last End of input range.
  208. * @param __result Output sum.
  209. * @return Iterator pointing just beyond the values written to __result.
  210. */
  211. template<typename _InputIterator, typename _OutputIterator>
  212. _OutputIterator
  213. partial_sum(_InputIterator __first, _InputIterator __last,
  214. _OutputIterator __result)
  215. {
  216. typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
  217. // concept requirements
  218. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  219. __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
  220. _ValueType>)
  221. __glibcxx_requires_valid_range(__first, __last);
  222. if (__first == __last)
  223. return __result;
  224. _ValueType __value = *__first;
  225. *__result = __value;
  226. while (++__first != __last)
  227. {
  228. __value = __value + *__first;
  229. *++__result = __value;
  230. }
  231. return ++__result;
  232. }
  233. /**
  234. * @brief Return list of partial sums
  235. *
  236. * Accumulates the values in the range [first,last) using @p __binary_op.
  237. * As each successive input value is added into the total, that partial sum
  238. * is written to @p __result. Therefore, the first value in @p __result is
  239. * the first value of the input, the second value in @p __result is the sum
  240. * of the first and second input values, and so on.
  241. *
  242. * @param __first Start of input range.
  243. * @param __last End of input range.
  244. * @param __result Output sum.
  245. * @param __binary_op Function object.
  246. * @return Iterator pointing just beyond the values written to __result.
  247. */
  248. template<typename _InputIterator, typename _OutputIterator,
  249. typename _BinaryOperation>
  250. _OutputIterator
  251. partial_sum(_InputIterator __first, _InputIterator __last,
  252. _OutputIterator __result, _BinaryOperation __binary_op)
  253. {
  254. typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
  255. // concept requirements
  256. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  257. __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
  258. _ValueType>)
  259. __glibcxx_requires_valid_range(__first, __last);
  260. if (__first == __last)
  261. return __result;
  262. _ValueType __value = *__first;
  263. *__result = __value;
  264. while (++__first != __last)
  265. {
  266. __value = __binary_op(__value, *__first);
  267. *++__result = __value;
  268. }
  269. return ++__result;
  270. }
  271. /**
  272. * @brief Return differences between adjacent values.
  273. *
  274. * Computes the difference between adjacent values in the range
  275. * [first,last) using operator-() and writes the result to @p __result.
  276. *
  277. * @param __first Start of input range.
  278. * @param __last End of input range.
  279. * @param __result Output sums.
  280. * @return Iterator pointing just beyond the values written to result.
  281. *
  282. * _GLIBCXX_RESOLVE_LIB_DEFECTS
  283. * DR 539. partial_sum and adjacent_difference should mention requirements
  284. */
  285. template<typename _InputIterator, typename _OutputIterator>
  286. _OutputIterator
  287. adjacent_difference(_InputIterator __first,
  288. _InputIterator __last, _OutputIterator __result)
  289. {
  290. typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
  291. // concept requirements
  292. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  293. __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
  294. _ValueType>)
  295. __glibcxx_requires_valid_range(__first, __last);
  296. if (__first == __last)
  297. return __result;
  298. _ValueType __value = *__first;
  299. *__result = __value;
  300. while (++__first != __last)
  301. {
  302. _ValueType __tmp = *__first;
  303. *++__result = __tmp - __value;
  304. __value = _GLIBCXX_MOVE(__tmp);
  305. }
  306. return ++__result;
  307. }
  308. /**
  309. * @brief Return differences between adjacent values.
  310. *
  311. * Computes the difference between adjacent values in the range
  312. * [__first,__last) using the function object @p __binary_op and writes the
  313. * result to @p __result.
  314. *
  315. * @param __first Start of input range.
  316. * @param __last End of input range.
  317. * @param __result Output sum.
  318. * @param __binary_op Function object.
  319. * @return Iterator pointing just beyond the values written to result.
  320. *
  321. * _GLIBCXX_RESOLVE_LIB_DEFECTS
  322. * DR 539. partial_sum and adjacent_difference should mention requirements
  323. */
  324. template<typename _InputIterator, typename _OutputIterator,
  325. typename _BinaryOperation>
  326. _OutputIterator
  327. adjacent_difference(_InputIterator __first, _InputIterator __last,
  328. _OutputIterator __result, _BinaryOperation __binary_op)
  329. {
  330. typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
  331. // concept requirements
  332. __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  333. __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
  334. _ValueType>)
  335. __glibcxx_requires_valid_range(__first, __last);
  336. if (__first == __last)
  337. return __result;
  338. _ValueType __value = *__first;
  339. *__result = __value;
  340. while (++__first != __last)
  341. {
  342. _ValueType __tmp = *__first;
  343. *++__result = __binary_op(__tmp, __value);
  344. __value = _GLIBCXX_MOVE(__tmp);
  345. }
  346. return ++__result;
  347. }
  348. _GLIBCXX_END_NAMESPACE_ALGO
  349. } // namespace std
  350. #endif /* _STL_NUMERIC_H */