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