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 | |
22 | #ifndef BOOST_RANGE_NUMERIC_HPP |
23 | #define BOOST_RANGE_NUMERIC_HPP |
24 | |
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> |
33 | #include <numeric> |
34 | |
35 | |
36 | namespace boost |
37 | { |
38 | template<class SinglePassRange, class Value> |
39 | inline Value accumulate(const SinglePassRange& rng, Value init) |
40 | { |
41 | BOOST_RANGE_CONCEPT_ASSERT(( |
42 | SinglePassRangeConcept<const SinglePassRange>)); |
43 | |
44 | return std::accumulate(boost::begin(rng), boost::end(rng), init); |
45 | } |
46 | |
47 | template<class SinglePassRange, class Value, class BinaryOperation> |
48 | inline Value accumulate(const SinglePassRange& rng, Value init, |
49 | BinaryOperation op) |
50 | { |
51 | BOOST_RANGE_CONCEPT_ASSERT(( |
52 | SinglePassRangeConcept<const SinglePassRange> )); |
53 | |
54 | return std::accumulate(boost::begin(rng), boost::end(rng), init, op); |
55 | } |
56 | |
57 | namespace range_detail |
58 | { |
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) |
65 | { |
66 | return true; |
67 | } |
68 | |
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) |
75 | { |
76 | return boost::size(rng2) >= boost::size(rng1); |
77 | } |
78 | |
79 | } // namespace range_detail |
80 | |
81 | template< |
82 | class SinglePassRange1, |
83 | class SinglePassRange2, |
84 | class Value |
85 | > |
86 | inline Value inner_product( |
87 | const SinglePassRange1& rng1, |
88 | const SinglePassRange2& rng2, |
89 | Value init) |
90 | { |
91 | BOOST_RANGE_CONCEPT_ASSERT(( |
92 | SinglePassRangeConcept<const SinglePassRange1>)); |
93 | |
94 | BOOST_RANGE_CONCEPT_ASSERT(( |
95 | SinglePassRangeConcept<const SinglePassRange2>)); |
96 | |
97 | BOOST_ASSERT( |
98 | range_detail::inner_product_precondition( |
99 | rng1, rng2, |
100 | typename range_category<const SinglePassRange1>::type(), |
101 | typename range_category<const SinglePassRange2>::type())); |
102 | |
103 | return std::inner_product( |
104 | boost::begin(rng1), boost::end(rng1), |
105 | boost::begin(rng2), init); |
106 | } |
107 | |
108 | template< |
109 | class SinglePassRange1, |
110 | class SinglePassRange2, |
111 | class Value, |
112 | class BinaryOperation1, |
113 | class BinaryOperation2 |
114 | > |
115 | inline Value inner_product( |
116 | const SinglePassRange1& rng1, |
117 | const SinglePassRange2& rng2, |
118 | Value init, |
119 | BinaryOperation1 op1, |
120 | BinaryOperation2 op2) |
121 | { |
122 | BOOST_RANGE_CONCEPT_ASSERT(( |
123 | SinglePassRangeConcept<const SinglePassRange1>)); |
124 | |
125 | BOOST_RANGE_CONCEPT_ASSERT(( |
126 | SinglePassRangeConcept<const SinglePassRange2>)); |
127 | |
128 | BOOST_ASSERT( |
129 | range_detail::inner_product_precondition( |
130 | rng1, rng2, |
131 | typename range_category<const SinglePassRange1>::type(), |
132 | typename range_category<const SinglePassRange2>::type())); |
133 | |
134 | return std::inner_product( |
135 | boost::begin(rng1), boost::end(rng1), |
136 | boost::begin(rng2), init, op1, op2); |
137 | } |
138 | |
139 | template<class SinglePassRange, class OutputIterator> |
140 | inline OutputIterator partial_sum(const SinglePassRange& rng, |
141 | OutputIterator result) |
142 | { |
143 | BOOST_RANGE_CONCEPT_ASSERT(( |
144 | SinglePassRangeConcept<const SinglePassRange>)); |
145 | |
146 | return std::partial_sum(boost::begin(rng), boost::end(rng), result); |
147 | } |
148 | |
149 | template<class SinglePassRange, class OutputIterator, class BinaryOperation> |
150 | inline OutputIterator partial_sum( |
151 | const SinglePassRange& rng, |
152 | OutputIterator result, |
153 | BinaryOperation op) |
154 | { |
155 | BOOST_RANGE_CONCEPT_ASSERT(( |
156 | SinglePassRangeConcept<const SinglePassRange>)); |
157 | |
158 | return std::partial_sum(boost::begin(rng), boost::end(rng), result, op); |
159 | } |
160 | |
161 | template<class SinglePassRange, class OutputIterator> |
162 | inline OutputIterator adjacent_difference( |
163 | const SinglePassRange& rng, |
164 | OutputIterator result) |
165 | { |
166 | BOOST_RANGE_CONCEPT_ASSERT(( |
167 | SinglePassRangeConcept<const SinglePassRange>)); |
168 | |
169 | return std::adjacent_difference(boost::begin(rng), boost::end(rng), |
170 | result); |
171 | } |
172 | |
173 | template<class SinglePassRange, class OutputIterator, class BinaryOperation> |
174 | inline OutputIterator adjacent_difference( |
175 | const SinglePassRange& rng, |
176 | OutputIterator result, |
177 | BinaryOperation op) |
178 | { |
179 | BOOST_RANGE_CONCEPT_ASSERT(( |
180 | SinglePassRangeConcept<const SinglePassRange>)); |
181 | |
182 | return std::adjacent_difference(boost::begin(rng), boost::end(rng), |
183 | result, op); |
184 | } |
185 | |
186 | } // namespace boost |
187 | |
188 | #endif |
189 | |