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)
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)
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)
16 // Contains range-based versions of the numeric std algorithms
22 #ifndef BOOST_RANGE_NUMERIC_HPP
23 #define BOOST_RANGE_NUMERIC_HPP
25 #include <boost/config.hpp>
26 #include <boost/assert.hpp>
27 #include <boost/range/begin.hpp>
28 #include <boost/range/end.hpp>
29 #include <boost/range/category.hpp>
30 #include <boost/range/concepts.hpp>
31 #include <boost/range/distance.hpp>
32 #include <boost/range/size.hpp>
38 template<class SinglePassRange, class Value>
39 inline Value accumulate(const SinglePassRange& rng, Value init)
41 BOOST_RANGE_CONCEPT_ASSERT((
42 SinglePassRangeConcept<const SinglePassRange>));
44 return std::accumulate(boost::begin(rng), boost::end(rng), init);
47 template<class SinglePassRange, class Value, class BinaryOperation>
48 inline Value accumulate(const SinglePassRange& rng, Value init,
51 BOOST_RANGE_CONCEPT_ASSERT((
52 SinglePassRangeConcept<const SinglePassRange> ));
54 return std::accumulate(boost::begin(rng), boost::end(rng), init, op);
57 namespace range_detail
59 template<class SinglePassRange1, class SinglePassRange2>
60 inline bool inner_product_precondition(
61 const SinglePassRange1&,
62 const SinglePassRange2&,
63 std::input_iterator_tag,
64 std::input_iterator_tag)
69 template<class SinglePassRange1, class SinglePassRange2>
70 inline bool inner_product_precondition(
71 const SinglePassRange1& rng1,
72 const SinglePassRange2& rng2,
73 std::forward_iterator_tag,
74 std::forward_iterator_tag)
76 return boost::size(rng2) >= boost::size(rng1);
79 } // namespace range_detail
82 class SinglePassRange1,
83 class SinglePassRange2,
86 inline Value inner_product(
87 const SinglePassRange1& rng1,
88 const SinglePassRange2& rng2,
91 BOOST_RANGE_CONCEPT_ASSERT((
92 SinglePassRangeConcept<const SinglePassRange1>));
94 BOOST_RANGE_CONCEPT_ASSERT((
95 SinglePassRangeConcept<const SinglePassRange2>));
98 range_detail::inner_product_precondition(
100 typename range_category<const SinglePassRange1>::type(),
101 typename range_category<const SinglePassRange2>::type()));
103 return std::inner_product(
104 boost::begin(rng1), boost::end(rng1),
105 boost::begin(rng2), init);
109 class SinglePassRange1,
110 class SinglePassRange2,
112 class BinaryOperation1,
113 class BinaryOperation2
115 inline Value inner_product(
116 const SinglePassRange1& rng1,
117 const SinglePassRange2& rng2,
119 BinaryOperation1 op1,
120 BinaryOperation2 op2)
122 BOOST_RANGE_CONCEPT_ASSERT((
123 SinglePassRangeConcept<const SinglePassRange1>));
125 BOOST_RANGE_CONCEPT_ASSERT((
126 SinglePassRangeConcept<const SinglePassRange2>));
129 range_detail::inner_product_precondition(
131 typename range_category<const SinglePassRange1>::type(),
132 typename range_category<const SinglePassRange2>::type()));
134 return std::inner_product(
135 boost::begin(rng1), boost::end(rng1),
136 boost::begin(rng2), init, op1, op2);
139 template<class SinglePassRange, class OutputIterator>
140 inline OutputIterator partial_sum(const SinglePassRange& rng,
141 OutputIterator result)
143 BOOST_RANGE_CONCEPT_ASSERT((
144 SinglePassRangeConcept<const SinglePassRange>));
146 return std::partial_sum(boost::begin(rng), boost::end(rng), result);
149 template<class SinglePassRange, class OutputIterator, class BinaryOperation>
150 inline OutputIterator partial_sum(
151 const SinglePassRange& rng,
152 OutputIterator result,
155 BOOST_RANGE_CONCEPT_ASSERT((
156 SinglePassRangeConcept<const SinglePassRange>));
158 return std::partial_sum(boost::begin(rng), boost::end(rng), result, op);
161 template<class SinglePassRange, class OutputIterator>
162 inline OutputIterator adjacent_difference(
163 const SinglePassRange& rng,
164 OutputIterator result)
166 BOOST_RANGE_CONCEPT_ASSERT((
167 SinglePassRangeConcept<const SinglePassRange>));
169 return std::adjacent_difference(boost::begin(rng), boost::end(rng),
173 template<class SinglePassRange, class OutputIterator, class BinaryOperation>
174 inline OutputIterator adjacent_difference(
175 const SinglePassRange& rng,
176 OutputIterator result,
179 BOOST_RANGE_CONCEPT_ASSERT((
180 SinglePassRangeConcept<const SinglePassRange>));
182 return std::adjacent_difference(boost::begin(rng), boost::end(rng),