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 {
199 typedef Left first_argument_type;
200 typedef Right second_argument_type;
201 typedef void result_type;
202
203 void operator ()(Left &left, Right &right) const
204 {
205 BOOST_ASSERT(left.size() == right.size());
206 for(std::size_t i = 0, size = left.size(); i != size; ++i)
207 {
208 if(numeric::less(right[i], left[i]))
209 {
210 left[i] = right[i];
211 }
212 }
213 }
214 };
215
216 ///////////////////////////////////////////////////////////////////////////////
217 // element-wise max of std::vector
218 template<typename Left, typename Right>
219 struct max_assign<Left, Right, std_vector_tag, std_vector_tag>
220 {
221 typedef Left first_argument_type;
222 typedef Right second_argument_type;
223 typedef void result_type;
224
225 void operator ()(Left &left, Right &right) const
226 {
227 BOOST_ASSERT(left.size() == right.size());
228 for(std::size_t i = 0, size = left.size(); i != size; ++i)
229 {
230 if(numeric::greater(right[i], left[i]))
231 {
232 left[i] = right[i];
233 }
234 }
235 }
236 };
237
238 // partial specialization for std::vector.
239 template<typename Left, typename Right>
240 struct fdiv<Left, Right, std_vector_tag, void>
241 : mpl::if_<
242 are_integral<typename Left::value_type, Right>
243 , divides<Left, double const>
244 , divides<Left, Right>
245 >::type
246 {};
247
248 // promote
249 template<typename To, typename From>
250 struct promote<To, From, std_vector_tag, std_vector_tag>
251 {
252 typedef From argument_type;
253 typedef To result_type;
254
255 To operator ()(From &arr) const
256 {
257 typename remove_const<To>::type res(arr.size());
258 for(std::size_t i = 0, size = arr.size(); i != size; ++i)
259 {
260 res[i] = numeric::promote<typename To::value_type>(arr[i]);
261 }
262 return res;
263 }
264 };
265
266 template<typename ToFrom>
267 struct promote<ToFrom, ToFrom, std_vector_tag, std_vector_tag>
268 {
269 typedef ToFrom argument_type;
270 typedef ToFrom result_type;
271
272 ToFrom &operator ()(ToFrom &tofrom) const
273 {
274 return tofrom;
275 }
276 };
277
278 ///////////////////////////////////////////////////////////////////////////////
279 // functional::as_min
280 template<typename T>
281 struct as_min<T, std_vector_tag>
282 {
283 typedef T argument_type;
284 typedef typename remove_const<T>::type result_type;
285
286 typename remove_const<T>::type operator ()(T &arr) const
287 {
288 return 0 == arr.size()
289 ? T()
290 : T(arr.size(), numeric::as_min(arr[0]));
291 }
292 };
293
294 ///////////////////////////////////////////////////////////////////////////////
295 // functional::as_max
296 template<typename T>
297 struct as_max<T, std_vector_tag>
298 {
299 typedef T argument_type;
300 typedef typename remove_const<T>::type result_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_max(arr[0]));
307 }
308 };
309
310 ///////////////////////////////////////////////////////////////////////////////
311 // functional::as_zero
312 template<typename T>
313 struct as_zero<T, std_vector_tag>
314 {
315 typedef T argument_type;
316 typedef typename remove_const<T>::type result_type;
317
318 typename remove_const<T>::type operator ()(T &arr) const
319 {
320 return 0 == arr.size()
321 ? T()
322 : T(arr.size(), numeric::as_zero(arr[0]));
323 }
324 };
325
326 ///////////////////////////////////////////////////////////////////////////////
327 // functional::as_one
328 template<typename T>
329 struct as_one<T, std_vector_tag>
330 {
331 typedef T argument_type;
332 typedef typename remove_const<T>::type result_type;
333
334 typename remove_const<T>::type operator ()(T &arr) const
335 {
336 return 0 == arr.size()
337 ? T()
338 : T(arr.size(), numeric::as_one(arr[0]));
339 }
340 };
341
342 } // namespace functional
343
344}} // namespace boost::numeric
345
346#endif
347
348

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