Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

414 lines
14KB

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