numeric.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2009-2014 Neil Groves.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. //
  6. // Copyright 2006 Thorsten Ottosen.
  7. // Distributed under the Boost Software License, Version 1.0. (See
  8. // accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Copyright 2004 Eric Niebler.
  12. // Distributed under the Boost Software License, Version 1.0. (See
  13. // accompanying file LICENSE_1_0.txt or copy at
  14. // http://www.boost.org/LICENSE_1_0.txt)
  15. //
  16. // Contains range-based versions of the numeric std algorithms
  17. //
  18. #if defined(_MSC_VER)
  19. #pragma once
  20. #endif
  21. #ifndef BOOST_RANGE_NUMERIC_HPP
  22. #define BOOST_RANGE_NUMERIC_HPP
  23. #include <boost/config.hpp>
  24. #include <boost/assert.hpp>
  25. #include <boost/range/begin.hpp>
  26. #include <boost/range/end.hpp>
  27. #include <boost/range/category.hpp>
  28. #include <boost/range/concepts.hpp>
  29. #include <boost/range/distance.hpp>
  30. #include <boost/range/size.hpp>
  31. #include <numeric>
  32. namespace boost
  33. {
  34. template<class SinglePassRange, class Value>
  35. inline Value accumulate(const SinglePassRange& rng, Value init)
  36. {
  37. BOOST_RANGE_CONCEPT_ASSERT((
  38. SinglePassRangeConcept<const SinglePassRange>));
  39. return std::accumulate(boost::begin(rng), boost::end(rng), init);
  40. }
  41. template<class SinglePassRange, class Value, class BinaryOperation>
  42. inline Value accumulate(const SinglePassRange& rng, Value init,
  43. BinaryOperation op)
  44. {
  45. BOOST_RANGE_CONCEPT_ASSERT((
  46. SinglePassRangeConcept<const SinglePassRange> ));
  47. return std::accumulate(boost::begin(rng), boost::end(rng), init, op);
  48. }
  49. namespace range_detail
  50. {
  51. template<class SinglePassRange1, class SinglePassRange2>
  52. inline bool inner_product_precondition(
  53. const SinglePassRange1&,
  54. const SinglePassRange2&,
  55. std::input_iterator_tag,
  56. std::input_iterator_tag)
  57. {
  58. return true;
  59. }
  60. template<class SinglePassRange1, class SinglePassRange2>
  61. inline bool inner_product_precondition(
  62. const SinglePassRange1& rng1,
  63. const SinglePassRange2& rng2,
  64. std::forward_iterator_tag,
  65. std::forward_iterator_tag)
  66. {
  67. return boost::size(rng2) >= boost::size(rng1);
  68. }
  69. } // namespace range_detail
  70. template<
  71. class SinglePassRange1,
  72. class SinglePassRange2,
  73. class Value
  74. >
  75. inline Value inner_product(
  76. const SinglePassRange1& rng1,
  77. const SinglePassRange2& rng2,
  78. Value init)
  79. {
  80. BOOST_RANGE_CONCEPT_ASSERT((
  81. SinglePassRangeConcept<const SinglePassRange1>));
  82. BOOST_RANGE_CONCEPT_ASSERT((
  83. SinglePassRangeConcept<const SinglePassRange2>));
  84. BOOST_ASSERT(
  85. range_detail::inner_product_precondition(
  86. rng1, rng2,
  87. typename range_category<const SinglePassRange1>::type(),
  88. typename range_category<const SinglePassRange2>::type()));
  89. return std::inner_product(
  90. boost::begin(rng1), boost::end(rng1),
  91. boost::begin(rng2), init);
  92. }
  93. template<
  94. class SinglePassRange1,
  95. class SinglePassRange2,
  96. class Value,
  97. class BinaryOperation1,
  98. class BinaryOperation2
  99. >
  100. inline Value inner_product(
  101. const SinglePassRange1& rng1,
  102. const SinglePassRange2& rng2,
  103. Value init,
  104. BinaryOperation1 op1,
  105. BinaryOperation2 op2)
  106. {
  107. BOOST_RANGE_CONCEPT_ASSERT((
  108. SinglePassRangeConcept<const SinglePassRange1>));
  109. BOOST_RANGE_CONCEPT_ASSERT((
  110. SinglePassRangeConcept<const SinglePassRange2>));
  111. BOOST_ASSERT(
  112. range_detail::inner_product_precondition(
  113. rng1, rng2,
  114. typename range_category<const SinglePassRange1>::type(),
  115. typename range_category<const SinglePassRange2>::type()));
  116. return std::inner_product(
  117. boost::begin(rng1), boost::end(rng1),
  118. boost::begin(rng2), init, op1, op2);
  119. }
  120. template<class SinglePassRange, class OutputIterator>
  121. inline OutputIterator partial_sum(const SinglePassRange& rng,
  122. OutputIterator result)
  123. {
  124. BOOST_RANGE_CONCEPT_ASSERT((
  125. SinglePassRangeConcept<const SinglePassRange>));
  126. return std::partial_sum(boost::begin(rng), boost::end(rng), result);
  127. }
  128. template<class SinglePassRange, class OutputIterator, class BinaryOperation>
  129. inline OutputIterator partial_sum(
  130. const SinglePassRange& rng,
  131. OutputIterator result,
  132. BinaryOperation op)
  133. {
  134. BOOST_RANGE_CONCEPT_ASSERT((
  135. SinglePassRangeConcept<const SinglePassRange>));
  136. return std::partial_sum(boost::begin(rng), boost::end(rng), result, op);
  137. }
  138. template<class SinglePassRange, class OutputIterator>
  139. inline OutputIterator adjacent_difference(
  140. const SinglePassRange& rng,
  141. OutputIterator result)
  142. {
  143. BOOST_RANGE_CONCEPT_ASSERT((
  144. SinglePassRangeConcept<const SinglePassRange>));
  145. return std::adjacent_difference(boost::begin(rng), boost::end(rng),
  146. result);
  147. }
  148. template<class SinglePassRange, class OutputIterator, class BinaryOperation>
  149. inline OutputIterator adjacent_difference(
  150. const SinglePassRange& rng,
  151. OutputIterator result,
  152. BinaryOperation op)
  153. {
  154. BOOST_RANGE_CONCEPT_ASSERT((
  155. SinglePassRangeConcept<const SinglePassRange>));
  156. return std::adjacent_difference(boost::begin(rng), boost::end(rng),
  157. result, op);
  158. }
  159. } // namespace boost
  160. #endif