1///////////////////////////////////////////////////////////////////////////////
2/// \file vector.hpp
3///
4// Copyright 2005 Eric Niebler. Distributed under the Boost
5// Software License, Version 1.0. (See accompanying file
6// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#ifndef BOOST_NUMERIC_FUNCTIONAL_VECTOR_HPP_EAN_12_12_2005
9#define BOOST_NUMERIC_FUNCTIONAL_VECTOR_HPP_EAN_12_12_2005
10
11#ifdef BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
12# error Include this file before boost/accumulators/numeric/functional.hpp
13#endif
14
15#include <vector>
16#include <functional>
17#include <boost/assert.hpp>
18#include <boost/mpl/and.hpp>
19#include <boost/mpl/not.hpp>
20#include <boost/utility/enable_if.hpp>
21#include <boost/type_traits/is_same.hpp>
22#include <boost/type_traits/is_scalar.hpp>
23#include <boost/type_traits/remove_const.hpp>
24#include <boost/typeof/std/vector.hpp>
25#include <boost/accumulators/numeric/functional_fwd.hpp>
26
27namespace boost { namespace numeric
28{
29 namespace operators
30 {
31 namespace acc_detail
32 {
33 template<typename Fun>
34 struct make_vector
35 {
36 typedef std::vector<typename Fun::result_type> type;
37 };
38 }
39
40 ///////////////////////////////////////////////////////////////////////////////
41 // Handle vector<Left> / Right where Right is a scalar.
42 template<typename Left, typename Right>
43 typename lazy_enable_if<
44 is_scalar<Right>
45 , acc_detail::make_vector<functional::divides<Left, Right> >
46 >::type
47 operator /(std::vector<Left> const &left, Right const &right)
48 {
49 typedef typename functional::divides<Left, Right>::result_type value_type;
50 std::vector<value_type> result(left.size());
51 for(std::size_t i = 0, size = result.size(); i != size; ++i)
52 {
53 result[i] = numeric::divides(left[i], right);
54 }
55 return result;
56 }
57
58 ///////////////////////////////////////////////////////////////////////////////
59 // Handle vector<Left> / vector<Right>.
60 template<typename Left, typename Right>
61 std::vector<typename functional::divides<Left, Right>::result_type>
62 operator /(std::vector<Left> const &left, std::vector<Right> const &right)
63 {
64 typedef typename functional::divides<Left, Right>::result_type value_type;
65 std::vector<value_type> result(left.size());
66 for(std::size_t i = 0, size = result.size(); i != size; ++i)
67 {
68 result[i] = numeric::divides(left[i], right[i]);
69 }
70 return result;
71 }
72
73 ///////////////////////////////////////////////////////////////////////////////
74 // Handle vector<Left> * Right where Right is a scalar.
75 template<typename Left, typename Right>
76 typename lazy_enable_if<
77 is_scalar<Right>
78 , acc_detail::make_vector<functional::multiplies<Left, Right> >
79 >::type
80 operator *(std::vector<Left> const &left, Right const &right)
81 {
82 typedef typename functional::multiplies<Left, Right>::result_type value_type;
83 std::vector<value_type> result(left.size());
84 for(std::size_t i = 0, size = result.size(); i != size; ++i)
85 {
86 result[i] = numeric::multiplies(left[i], right);
87 }
88 return result;
89 }
90
91 ///////////////////////////////////////////////////////////////////////////////
92 // Handle Left * vector<Right> where Left is a scalar.
93 template<typename Left, typename Right>
94 typename lazy_enable_if<
95 is_scalar<Left>
96 , acc_detail::make_vector<functional::multiplies<Left, Right> >
97 >::type
98 operator *(Left const &left, std::vector<Right> const &right)
99 {
100 typedef typename functional::multiplies<Left, Right>::result_type value_type;
101 std::vector<value_type> result(right.size());
102 for(std::size_t i = 0, size = result.size(); i != size; ++i)
103 {
104 result[i] = numeric::multiplies(left, right[i]);
105 }
106 return result;
107 }
108
109 ///////////////////////////////////////////////////////////////////////////////
110 // Handle vector<Left> * vector<Right>
111 template<typename Left, typename Right>
112 std::vector<typename functional::multiplies<Left, Right>::result_type>
113 operator *(std::vector<Left> const &left, std::vector<Right> const &right)
114 {
115 typedef typename functional::multiplies<Left, Right>::result_type value_type;
116 std::vector<value_type> result(left.size());
117 for(std::size_t i = 0, size = result.size(); i != size; ++i)
118 {
119 result[i] = numeric::multiplies(left[i], right[i]);
120 }
121 return result;
122 }
123
124 ///////////////////////////////////////////////////////////////////////////////
125 // Handle vector<Left> + vector<Right>
126 template<typename Left, typename Right>
127 std::vector<typename functional::plus<Left, Right>::result_type>
128 operator +(std::vector<Left> const &left, std::vector<Right> const &right)
129 {
130 typedef typename functional::plus<Left, Right>::result_type value_type;
131 std::vector<value_type> result(left.size());
132 for(std::size_t i = 0, size = result.size(); i != size; ++i)
133 {
134 result[i] = numeric::plus(left[i], right[i]);
135 }
136 return result;
137 }
138
139 ///////////////////////////////////////////////////////////////////////////////
140 // Handle vector<Left> - vector<Right>
141 template<typename Left, typename Right>
142 std::vector<typename functional::minus<Left, Right>::result_type>
143 operator -(std::vector<Left> const &left, std::vector<Right> const &right)
144 {
145 typedef typename functional::minus<Left, Right>::result_type value_type;
146 std::vector<value_type> result(left.size());
147 for(std::size_t i = 0, size = result.size(); i != size; ++i)
148 {
149 result[i] = numeric::minus(left[i], right[i]);
150 }
151 return result;
152 }
153
154 ///////////////////////////////////////////////////////////////////////////////
155 // Handle vector<Left> += vector<Left>
156 template<typename Left>
157 std::vector<Left> &
158 operator +=(std::vector<Left> &left, std::vector<Left> const &right)
159 {
160 BOOST_ASSERT(left.size() == right.size());
161 for(std::size_t i = 0, size = left.size(); i != size; ++i)
162 {
163 numeric::plus_assign(left[i], right[i]);
164 }
165 return left;
166 }
167
168 ///////////////////////////////////////////////////////////////////////////////
169 // Handle -vector<Arg>
170 template<typename Arg>
171 std::vector<typename functional::unary_minus<Arg>::result_type>
172 operator -(std::vector<Arg> const &arg)
173 {
174 typedef typename functional::unary_minus<Arg>::result_type value_type;
175 std::vector<value_type> result(arg.size());
176 for(std::size_t i = 0, size = result.size(); i != size; ++i)
177 {
178 result[i] = numeric::unary_minus(arg[i]);
179 }
180 return result;
181 }
182 }
183
184 namespace functional
185 {
186 struct std_vector_tag;
187
188 template<typename T, typename Al>
189 struct tag<std::vector<T, Al> >
190 {
191 typedef std_vector_tag type;
192 };
193
194 ///////////////////////////////////////////////////////////////////////////////
195 // element-wise min of std::vector
196 template<typename Left, typename Right>
197 struct min_assign<Left, Right, std_vector_tag, std_vector_tag>
198 : std::binary_function<Left, Right, void>
199 {
200 void operator ()(Left &left, Right &right) const
201 {
202 BOOST_ASSERT(left.size() == right.size());
203 for(std::size_t i = 0, size = left.size(); i != size; ++i)
204 {
205 if(numeric::less(right[i], left[i]))
206 {
207 left[i] = right[i];
208 }
209 }
210 }
211 };
212
213 ///////////////////////////////////////////////////////////////////////////////
214 // element-wise max of std::vector
215 template<typename Left, typename Right>
216 struct max_assign<Left, Right, std_vector_tag, std_vector_tag>
217 : std::binary_function<Left, Right, void>
218 {
219 void operator ()(Left &left, Right &right) const
220 {
221 BOOST_ASSERT(left.size() == right.size());
222 for(std::size_t i = 0, size = left.size(); i != size; ++i)
223 {
224 if(numeric::greater(right[i], left[i]))
225 {
226 left[i] = right[i];
227 }
228 }
229 }
230 };
231
232 // partial specialization for std::vector.
233 template<typename Left, typename Right>
234 struct fdiv<Left, Right, std_vector_tag, void>
235 : mpl::if_<
236 are_integral<typename Left::value_type, Right>
237 , divides<Left, double const>
238 , divides<Left, Right>
239 >::type
240 {};
241
242 // promote
243 template<typename To, typename From>
244 struct promote<To, From, std_vector_tag, std_vector_tag>
245 : std::unary_function<From, To>
246 {
247 To operator ()(From &arr) const
248 {
249 typename remove_const<To>::type res(arr.size());
250 for(std::size_t i = 0, size = arr.size(); i != size; ++i)
251 {
252 res[i] = numeric::promote<typename To::value_type>(arr[i]);
253 }
254 return res;
255 }
256 };
257
258 template<typename ToFrom>
259 struct promote<ToFrom, ToFrom, std_vector_tag, std_vector_tag>
260 : std::unary_function<ToFrom, ToFrom>
261 {
262 ToFrom &operator ()(ToFrom &tofrom) const
263 {
264 return tofrom;
265 }
266 };
267
268 ///////////////////////////////////////////////////////////////////////////////
269 // functional::as_min
270 template<typename T>
271 struct as_min<T, std_vector_tag>
272 : std::unary_function<T, typename remove_const<T>::type>
273 {
274 typename remove_const<T>::type operator ()(T &arr) const
275 {
276 return 0 == arr.size()
277 ? T()
278 : T(arr.size(), numeric::as_min(arr[0]));
279 }
280 };
281
282 ///////////////////////////////////////////////////////////////////////////////
283 // functional::as_max
284 template<typename T>
285 struct as_max<T, std_vector_tag>
286 : std::unary_function<T, typename remove_const<T>::type>
287 {
288 typename remove_const<T>::type operator ()(T &arr) const
289 {
290 return 0 == arr.size()
291 ? T()
292 : T(arr.size(), numeric::as_max(arr[0]));
293 }
294 };
295
296 ///////////////////////////////////////////////////////////////////////////////
297 // functional::as_zero
298 template<typename T>
299 struct as_zero<T, std_vector_tag>
300 : std::unary_function<T, typename remove_const<T>::type>
301 {
302 typename remove_const<T>::type operator ()(T &arr) const
303 {
304 return 0 == arr.size()
305 ? T()
306 : T(arr.size(), numeric::as_zero(arr[0]));
307 }
308 };
309
310 ///////////////////////////////////////////////////////////////////////////////
311 // functional::as_one
312 template<typename T>
313 struct as_one<T, std_vector_tag>
314 : std::unary_function<T, typename remove_const<T>::type>
315 {
316 typename remove_const<T>::type operator ()(T &arr) const
317 {
318 return 0 == arr.size()
319 ? T()
320 : T(arr.size(), numeric::as_one(arr[0]));
321 }
322 };
323
324 } // namespace functional
325
326}} // namespace boost::numeric
327
328#endif
329
330

source code of boost/boost/accumulators/numeric/functional/vector.hpp