Chris@16
|
1 //
|
Chris@16
|
2 // Copyright (c) 2000-2002
|
Chris@16
|
3 // Joerg Walter, Mathias Koch
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //
|
Chris@16
|
9 // The authors gratefully acknowledge the support of
|
Chris@16
|
10 // GeNeSys mbH & Co. KG in producing this work.
|
Chris@16
|
11 //
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef _BOOST_UBLAS_TRAITS_
|
Chris@16
|
14 #define _BOOST_UBLAS_TRAITS_
|
Chris@16
|
15
|
Chris@16
|
16 #include <iterator>
|
Chris@16
|
17 #include <complex>
|
Chris@16
|
18 #include <boost/config/no_tr1/cmath.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/numeric/ublas/detail/config.hpp>
|
Chris@16
|
21 #include <boost/numeric/ublas/detail/iterator.hpp>
|
Chris@16
|
22 #include <boost/numeric/ublas/detail/returntype_deduction.hpp>
|
Chris@101
|
23 #ifdef BOOST_UBLAS_USE_INTERVAL
|
Chris@101
|
24 #include <boost/numeric/interval.hpp>
|
Chris@101
|
25 #endif
|
Chris@16
|
26
|
Chris@16
|
27 #include <boost/type_traits.hpp>
|
Chris@16
|
28 #include <complex>
|
Chris@16
|
29 #include <boost/typeof/typeof.hpp>
|
Chris@16
|
30 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
31 #include <boost/type_traits/is_float.hpp>
|
Chris@16
|
32 #include <boost/type_traits/is_integral.hpp>
|
Chris@101
|
33 #include <boost/type_traits/is_unsigned.hpp>
|
Chris@16
|
34 #include <boost/mpl/and.hpp>
|
Chris@16
|
35
|
Chris@16
|
36 // anonymous namespace to avoid ADL issues
|
Chris@16
|
37 namespace {
|
Chris@16
|
38 template<class T> T boost_numeric_ublas_sqrt (const T& t) {
|
Chris@16
|
39 using namespace std;
|
Chris@16
|
40 // we'll find either std::sqrt or else another version via ADL:
|
Chris@16
|
41 return sqrt (t);
|
Chris@16
|
42 }
|
Chris@101
|
43
|
Chris@101
|
44 template<typename T>
|
Chris@101
|
45 inline typename boost::disable_if<
|
Chris@101
|
46 boost::is_unsigned<T>, T >::type
|
Chris@101
|
47 boost_numeric_ublas_abs (const T &t ) {
|
Chris@101
|
48 using namespace std;
|
Chris@101
|
49 return abs( t );
|
Chris@101
|
50 }
|
Chris@101
|
51
|
Chris@101
|
52 template<typename T>
|
Chris@101
|
53 inline typename boost::enable_if<
|
Chris@101
|
54 boost::is_unsigned<T>, T >::type
|
Chris@101
|
55 boost_numeric_ublas_abs (const T &t ) {
|
Chris@101
|
56 return t;
|
Chris@101
|
57 }
|
Chris@16
|
58 }
|
Chris@16
|
59
|
Chris@16
|
60 namespace boost { namespace numeric { namespace ublas {
|
Chris@16
|
61
|
Chris@101
|
62
|
Chris@101
|
63 template<typename R, typename I>
|
Chris@101
|
64 typename boost::enable_if<
|
Chris@101
|
65 mpl::and_<
|
Chris@101
|
66 boost::is_float<R>,
|
Chris@101
|
67 boost::is_integral<I>
|
Chris@101
|
68 >,
|
Chris@101
|
69 std::complex<R> >::type inline operator+ (I in1, std::complex<R> const& in2 ) {
|
Chris@101
|
70 return R (in1) + in2;
|
Chris@101
|
71 }
|
Chris@101
|
72
|
Chris@101
|
73 template<typename R, typename I>
|
Chris@101
|
74 typename boost::enable_if<
|
Chris@101
|
75 mpl::and_<
|
Chris@101
|
76 boost::is_float<R>,
|
Chris@101
|
77 boost::is_integral<I>
|
Chris@101
|
78 >,
|
Chris@101
|
79 std::complex<R> >::type inline operator+ (std::complex<R> const& in1, I in2) {
|
Chris@101
|
80 return in1 + R (in2);
|
Chris@101
|
81 }
|
Chris@101
|
82
|
Chris@101
|
83 template<typename R, typename I>
|
Chris@101
|
84 typename boost::enable_if<
|
Chris@101
|
85 mpl::and_<
|
Chris@101
|
86 boost::is_float<R>,
|
Chris@101
|
87 boost::is_integral<I>
|
Chris@101
|
88 >,
|
Chris@101
|
89 std::complex<R> >::type inline operator- (I in1, std::complex<R> const& in2) {
|
Chris@101
|
90 return R (in1) - in2;
|
Chris@101
|
91 }
|
Chris@101
|
92
|
Chris@101
|
93 template<typename R, typename I>
|
Chris@101
|
94 typename boost::enable_if<
|
Chris@101
|
95 mpl::and_<
|
Chris@101
|
96 boost::is_float<R>,
|
Chris@101
|
97 boost::is_integral<I>
|
Chris@101
|
98 >,
|
Chris@101
|
99 std::complex<R> >::type inline operator- (std::complex<R> const& in1, I in2) {
|
Chris@101
|
100 return in1 - R (in2);
|
Chris@101
|
101 }
|
Chris@101
|
102
|
Chris@101
|
103 template<typename R, typename I>
|
Chris@101
|
104 typename boost::enable_if<
|
Chris@101
|
105 mpl::and_<
|
Chris@101
|
106 boost::is_float<R>,
|
Chris@101
|
107 boost::is_integral<I>
|
Chris@101
|
108 >,
|
Chris@101
|
109 std::complex<R> >::type inline operator* (I in1, std::complex<R> const& in2) {
|
Chris@101
|
110 return R (in1) * in2;
|
Chris@101
|
111 }
|
Chris@101
|
112
|
Chris@101
|
113 template<typename R, typename I>
|
Chris@101
|
114 typename boost::enable_if<
|
Chris@101
|
115 mpl::and_<
|
Chris@101
|
116 boost::is_float<R>,
|
Chris@101
|
117 boost::is_integral<I>
|
Chris@101
|
118 >,
|
Chris@101
|
119 std::complex<R> >::type inline operator* (std::complex<R> const& in1, I in2) {
|
Chris@101
|
120 return in1 * R(in2);
|
Chris@101
|
121 }
|
Chris@101
|
122
|
Chris@101
|
123 template<typename R, typename I>
|
Chris@101
|
124 typename boost::enable_if<
|
Chris@101
|
125 mpl::and_<
|
Chris@101
|
126 boost::is_float<R>,
|
Chris@101
|
127 boost::is_integral<I>
|
Chris@101
|
128 >,
|
Chris@101
|
129 std::complex<R> >::type inline operator/ (I in1, std::complex<R> const& in2) {
|
Chris@101
|
130 return R(in1) / in2;
|
Chris@101
|
131 }
|
Chris@101
|
132
|
Chris@101
|
133 template<typename R, typename I>
|
Chris@101
|
134 typename boost::enable_if<
|
Chris@101
|
135 mpl::and_<
|
Chris@101
|
136 boost::is_float<R>,
|
Chris@101
|
137 boost::is_integral<I>
|
Chris@101
|
138 >,
|
Chris@101
|
139 std::complex<R> >::type inline operator/ (std::complex<R> const& in1, I in2) {
|
Chris@101
|
140 return in1 / R (in2);
|
Chris@101
|
141 }
|
Chris@101
|
142
|
Chris@16
|
143 // Use Joel de Guzman's return type deduction
|
Chris@16
|
144 // uBLAS assumes a common return type for all binary arithmetic operators
|
Chris@16
|
145 template<class X, class Y>
|
Chris@16
|
146 struct promote_traits {
|
Chris@16
|
147 typedef type_deduction_detail::base_result_of<X, Y> base_type;
|
Chris@16
|
148 static typename base_type::x_type x;
|
Chris@16
|
149 static typename base_type::y_type y;
|
Chris@16
|
150 static const std::size_t size = sizeof (
|
Chris@16
|
151 type_deduction_detail::test<
|
Chris@16
|
152 typename base_type::x_type
|
Chris@16
|
153 , typename base_type::y_type
|
Chris@16
|
154 >(x + y) // Use x+y to stand of all the arithmetic actions
|
Chris@16
|
155 );
|
Chris@16
|
156
|
Chris@16
|
157 static const std::size_t index = (size / sizeof (char)) - 1;
|
Chris@16
|
158 typedef typename mpl::at_c<
|
Chris@16
|
159 typename base_type::types, index>::type id;
|
Chris@16
|
160 typedef typename id::type promote_type;
|
Chris@16
|
161 };
|
Chris@16
|
162
|
Chris@16
|
163
|
Chris@16
|
164
|
Chris@16
|
165 // Type traits - generic numeric properties and functions
|
Chris@16
|
166 template<class T>
|
Chris@16
|
167 struct type_traits;
|
Chris@16
|
168
|
Chris@16
|
169 // Define properties for a generic scalar type
|
Chris@16
|
170 template<class T>
|
Chris@16
|
171 struct scalar_traits {
|
Chris@16
|
172 typedef scalar_traits<T> self_type;
|
Chris@16
|
173 typedef T value_type;
|
Chris@16
|
174 typedef const T &const_reference;
|
Chris@16
|
175 typedef T &reference;
|
Chris@16
|
176
|
Chris@16
|
177 typedef T real_type;
|
Chris@16
|
178 typedef real_type precision_type; // we do not know what type has more precision then the real_type
|
Chris@16
|
179
|
Chris@16
|
180 static const unsigned plus_complexity = 1;
|
Chris@16
|
181 static const unsigned multiplies_complexity = 1;
|
Chris@16
|
182
|
Chris@16
|
183 static
|
Chris@16
|
184 BOOST_UBLAS_INLINE
|
Chris@16
|
185 real_type real (const_reference t) {
|
Chris@16
|
186 return t;
|
Chris@16
|
187 }
|
Chris@16
|
188 static
|
Chris@16
|
189 BOOST_UBLAS_INLINE
|
Chris@16
|
190 real_type imag (const_reference /*t*/) {
|
Chris@16
|
191 return 0;
|
Chris@16
|
192 }
|
Chris@16
|
193 static
|
Chris@16
|
194 BOOST_UBLAS_INLINE
|
Chris@16
|
195 value_type conj (const_reference t) {
|
Chris@16
|
196 return t;
|
Chris@16
|
197 }
|
Chris@16
|
198
|
Chris@16
|
199 static
|
Chris@16
|
200 BOOST_UBLAS_INLINE
|
Chris@16
|
201 real_type type_abs (const_reference t) {
|
Chris@16
|
202 return boost_numeric_ublas_abs (t);
|
Chris@16
|
203 }
|
Chris@16
|
204 static
|
Chris@16
|
205 BOOST_UBLAS_INLINE
|
Chris@16
|
206 value_type type_sqrt (const_reference t) {
|
Chris@16
|
207 // force a type conversion back to value_type for intgral types
|
Chris@16
|
208 return value_type (boost_numeric_ublas_sqrt (t));
|
Chris@16
|
209 }
|
Chris@16
|
210
|
Chris@16
|
211 static
|
Chris@16
|
212 BOOST_UBLAS_INLINE
|
Chris@16
|
213 real_type norm_1 (const_reference t) {
|
Chris@16
|
214 return self_type::type_abs (t);
|
Chris@16
|
215 }
|
Chris@16
|
216 static
|
Chris@16
|
217 BOOST_UBLAS_INLINE
|
Chris@16
|
218 real_type norm_2 (const_reference t) {
|
Chris@16
|
219 return self_type::type_abs (t);
|
Chris@16
|
220 }
|
Chris@16
|
221 static
|
Chris@16
|
222 BOOST_UBLAS_INLINE
|
Chris@16
|
223 real_type norm_inf (const_reference t) {
|
Chris@16
|
224 return self_type::type_abs (t);
|
Chris@16
|
225 }
|
Chris@16
|
226
|
Chris@16
|
227 static
|
Chris@16
|
228 BOOST_UBLAS_INLINE
|
Chris@16
|
229 bool equals (const_reference t1, const_reference t2) {
|
Chris@16
|
230 return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
|
Chris@16
|
231 (std::max) ((std::max) (self_type::norm_inf (t1),
|
Chris@16
|
232 self_type::norm_inf (t2)),
|
Chris@16
|
233 BOOST_UBLAS_TYPE_CHECK_MIN);
|
Chris@16
|
234 }
|
Chris@16
|
235 };
|
Chris@16
|
236
|
Chris@16
|
237 // Define default type traits, assume T is a scalar type
|
Chris@16
|
238 template<class T>
|
Chris@16
|
239 struct type_traits : scalar_traits <T> {
|
Chris@16
|
240 typedef type_traits<T> self_type;
|
Chris@16
|
241 typedef T value_type;
|
Chris@16
|
242 typedef const T &const_reference;
|
Chris@16
|
243 typedef T &reference;
|
Chris@16
|
244
|
Chris@16
|
245 typedef T real_type;
|
Chris@16
|
246 typedef real_type precision_type;
|
Chris@16
|
247 static const unsigned multiplies_complexity = 1;
|
Chris@16
|
248
|
Chris@16
|
249 };
|
Chris@16
|
250
|
Chris@16
|
251 // Define real type traits
|
Chris@16
|
252 template<>
|
Chris@16
|
253 struct type_traits<float> : scalar_traits<float> {
|
Chris@16
|
254 typedef type_traits<float> self_type;
|
Chris@16
|
255 typedef float value_type;
|
Chris@16
|
256 typedef const value_type &const_reference;
|
Chris@16
|
257 typedef value_type &reference;
|
Chris@16
|
258 typedef value_type real_type;
|
Chris@16
|
259 typedef double precision_type;
|
Chris@16
|
260 };
|
Chris@16
|
261 template<>
|
Chris@16
|
262 struct type_traits<double> : scalar_traits<double> {
|
Chris@16
|
263 typedef type_traits<double> self_type;
|
Chris@16
|
264 typedef double value_type;
|
Chris@16
|
265 typedef const value_type &const_reference;
|
Chris@16
|
266 typedef value_type &reference;
|
Chris@16
|
267 typedef value_type real_type;
|
Chris@16
|
268 typedef long double precision_type;
|
Chris@16
|
269 };
|
Chris@16
|
270 template<>
|
Chris@16
|
271 struct type_traits<long double> : scalar_traits<long double> {
|
Chris@16
|
272 typedef type_traits<long double> self_type;
|
Chris@16
|
273 typedef long double value_type;
|
Chris@16
|
274 typedef const value_type &const_reference;
|
Chris@16
|
275 typedef value_type &reference;
|
Chris@16
|
276 typedef value_type real_type;
|
Chris@16
|
277 typedef value_type precision_type;
|
Chris@16
|
278 };
|
Chris@16
|
279
|
Chris@16
|
280 // Define properties for a generic complex type
|
Chris@16
|
281 template<class T>
|
Chris@16
|
282 struct complex_traits {
|
Chris@16
|
283 typedef complex_traits<T> self_type;
|
Chris@16
|
284 typedef T value_type;
|
Chris@16
|
285 typedef const T &const_reference;
|
Chris@16
|
286 typedef T &reference;
|
Chris@16
|
287
|
Chris@16
|
288 typedef typename T::value_type real_type;
|
Chris@16
|
289 typedef real_type precision_type; // we do not know what type has more precision then the real_type
|
Chris@16
|
290
|
Chris@16
|
291 static const unsigned plus_complexity = 2;
|
Chris@16
|
292 static const unsigned multiplies_complexity = 6;
|
Chris@16
|
293
|
Chris@16
|
294 static
|
Chris@16
|
295 BOOST_UBLAS_INLINE
|
Chris@16
|
296 real_type real (const_reference t) {
|
Chris@16
|
297 return std::real (t);
|
Chris@16
|
298 }
|
Chris@16
|
299 static
|
Chris@16
|
300 BOOST_UBLAS_INLINE
|
Chris@16
|
301 real_type imag (const_reference t) {
|
Chris@16
|
302 return std::imag (t);
|
Chris@16
|
303 }
|
Chris@16
|
304 static
|
Chris@16
|
305 BOOST_UBLAS_INLINE
|
Chris@16
|
306 value_type conj (const_reference t) {
|
Chris@16
|
307 return std::conj (t);
|
Chris@16
|
308 }
|
Chris@16
|
309
|
Chris@16
|
310 static
|
Chris@16
|
311 BOOST_UBLAS_INLINE
|
Chris@16
|
312 real_type type_abs (const_reference t) {
|
Chris@16
|
313 return abs (t);
|
Chris@16
|
314 }
|
Chris@16
|
315 static
|
Chris@16
|
316 BOOST_UBLAS_INLINE
|
Chris@16
|
317 value_type type_sqrt (const_reference t) {
|
Chris@16
|
318 return sqrt (t);
|
Chris@16
|
319 }
|
Chris@16
|
320
|
Chris@16
|
321 static
|
Chris@16
|
322 BOOST_UBLAS_INLINE
|
Chris@16
|
323 real_type norm_1 (const_reference t) {
|
Chris@16
|
324 return self_type::type_abs (t);
|
Chris@16
|
325 // original computation has been replaced because a complex number should behave like a scalar type
|
Chris@16
|
326 // return type_traits<real_type>::type_abs (self_type::real (t)) +
|
Chris@16
|
327 // type_traits<real_type>::type_abs (self_type::imag (t));
|
Chris@16
|
328 }
|
Chris@16
|
329 static
|
Chris@16
|
330 BOOST_UBLAS_INLINE
|
Chris@16
|
331 real_type norm_2 (const_reference t) {
|
Chris@16
|
332 return self_type::type_abs (t);
|
Chris@16
|
333 }
|
Chris@16
|
334 static
|
Chris@16
|
335 BOOST_UBLAS_INLINE
|
Chris@16
|
336 real_type norm_inf (const_reference t) {
|
Chris@16
|
337 return self_type::type_abs (t);
|
Chris@16
|
338 // original computation has been replaced because a complex number should behave like a scalar type
|
Chris@16
|
339 // return (std::max) (type_traits<real_type>::type_abs (self_type::real (t)),
|
Chris@16
|
340 // type_traits<real_type>::type_abs (self_type::imag (t)));
|
Chris@16
|
341 }
|
Chris@16
|
342
|
Chris@16
|
343 static
|
Chris@16
|
344 BOOST_UBLAS_INLINE
|
Chris@16
|
345 bool equals (const_reference t1, const_reference t2) {
|
Chris@16
|
346 return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
|
Chris@16
|
347 (std::max) ((std::max) (self_type::norm_inf (t1),
|
Chris@16
|
348 self_type::norm_inf (t2)),
|
Chris@16
|
349 BOOST_UBLAS_TYPE_CHECK_MIN);
|
Chris@16
|
350 }
|
Chris@16
|
351 };
|
Chris@16
|
352
|
Chris@16
|
353 // Define complex type traits
|
Chris@16
|
354 template<>
|
Chris@16
|
355 struct type_traits<std::complex<float> > : complex_traits<std::complex<float> >{
|
Chris@16
|
356 typedef type_traits<std::complex<float> > self_type;
|
Chris@16
|
357 typedef std::complex<float> value_type;
|
Chris@16
|
358 typedef const value_type &const_reference;
|
Chris@16
|
359 typedef value_type &reference;
|
Chris@16
|
360 typedef float real_type;
|
Chris@16
|
361 typedef std::complex<double> precision_type;
|
Chris@16
|
362
|
Chris@16
|
363 };
|
Chris@16
|
364 template<>
|
Chris@16
|
365 struct type_traits<std::complex<double> > : complex_traits<std::complex<double> >{
|
Chris@16
|
366 typedef type_traits<std::complex<double> > self_type;
|
Chris@16
|
367 typedef std::complex<double> value_type;
|
Chris@16
|
368 typedef const value_type &const_reference;
|
Chris@16
|
369 typedef value_type &reference;
|
Chris@16
|
370 typedef double real_type;
|
Chris@16
|
371 typedef std::complex<long double> precision_type;
|
Chris@16
|
372 };
|
Chris@16
|
373 template<>
|
Chris@16
|
374 struct type_traits<std::complex<long double> > : complex_traits<std::complex<long double> > {
|
Chris@16
|
375 typedef type_traits<std::complex<long double> > self_type;
|
Chris@16
|
376 typedef std::complex<long double> value_type;
|
Chris@16
|
377 typedef const value_type &const_reference;
|
Chris@16
|
378 typedef value_type &reference;
|
Chris@16
|
379 typedef long double real_type;
|
Chris@16
|
380 typedef value_type precision_type;
|
Chris@16
|
381 };
|
Chris@16
|
382
|
Chris@16
|
383 #ifdef BOOST_UBLAS_USE_INTERVAL
|
Chris@16
|
384 // Define scalar interval type traits
|
Chris@16
|
385 template<>
|
Chris@16
|
386 struct type_traits<boost::numeric::interval<float> > : scalar_traits<boost::numeric::interval<float> > {
|
Chris@16
|
387 typedef type_traits<boost::numeric::interval<float> > self_type;
|
Chris@16
|
388 typedef boost::numeric::interval<float> value_type;
|
Chris@16
|
389 typedef const value_type &const_reference;
|
Chris@16
|
390 typedef value_type &reference;
|
Chris@16
|
391 typedef value_type real_type;
|
Chris@16
|
392 typedef boost::numeric::interval<double> precision_type;
|
Chris@16
|
393
|
Chris@16
|
394 };
|
Chris@16
|
395 template<>
|
Chris@16
|
396 struct type_traits<boost::numeric::interval<double> > : scalar_traits<boost::numeric::interval<double> > {
|
Chris@16
|
397 typedef type_traits<boost::numeric::interval<double> > self_type;
|
Chris@16
|
398 typedef boost::numeric::interval<double> value_type;
|
Chris@16
|
399 typedef const value_type &const_reference;
|
Chris@16
|
400 typedef value_type &reference;
|
Chris@16
|
401 typedef value_type real_type;
|
Chris@16
|
402 typedef boost::numeric::interval<long double> precision_type;
|
Chris@16
|
403 };
|
Chris@16
|
404 template<>
|
Chris@16
|
405 struct type_traits<boost::numeric::interval<long double> > : scalar_traits<boost::numeric::interval<long double> > {
|
Chris@16
|
406 typedef type_traits<boost::numeric::interval<long double> > self_type;
|
Chris@16
|
407 typedef boost::numeric::interval<long double> value_type;
|
Chris@16
|
408 typedef const value_type &const_reference;
|
Chris@16
|
409 typedef value_type &reference;
|
Chris@16
|
410 typedef value_type real_type;
|
Chris@16
|
411 typedef value_type precision_type;
|
Chris@16
|
412 };
|
Chris@16
|
413 #endif
|
Chris@16
|
414
|
Chris@16
|
415
|
Chris@16
|
416 // Storage tags -- hierarchical definition of storage characteristics
|
Chris@16
|
417
|
Chris@16
|
418 struct unknown_storage_tag {};
|
Chris@16
|
419 struct sparse_proxy_tag: public unknown_storage_tag {};
|
Chris@16
|
420 struct sparse_tag: public sparse_proxy_tag {};
|
Chris@16
|
421 struct packed_proxy_tag: public sparse_proxy_tag {};
|
Chris@16
|
422 struct packed_tag: public packed_proxy_tag {};
|
Chris@16
|
423 struct dense_proxy_tag: public packed_proxy_tag {};
|
Chris@16
|
424 struct dense_tag: public dense_proxy_tag {};
|
Chris@16
|
425
|
Chris@16
|
426 template<class S1, class S2>
|
Chris@16
|
427 struct storage_restrict_traits {
|
Chris@16
|
428 typedef S1 storage_category;
|
Chris@16
|
429 };
|
Chris@16
|
430
|
Chris@16
|
431 template<>
|
Chris@16
|
432 struct storage_restrict_traits<sparse_tag, dense_proxy_tag> {
|
Chris@16
|
433 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
434 };
|
Chris@16
|
435 template<>
|
Chris@16
|
436 struct storage_restrict_traits<sparse_tag, packed_proxy_tag> {
|
Chris@16
|
437 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
438 };
|
Chris@16
|
439 template<>
|
Chris@16
|
440 struct storage_restrict_traits<sparse_tag, sparse_proxy_tag> {
|
Chris@16
|
441 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
442 };
|
Chris@16
|
443
|
Chris@16
|
444 template<>
|
Chris@16
|
445 struct storage_restrict_traits<packed_tag, dense_proxy_tag> {
|
Chris@16
|
446 typedef packed_proxy_tag storage_category;
|
Chris@16
|
447 };
|
Chris@16
|
448 template<>
|
Chris@16
|
449 struct storage_restrict_traits<packed_tag, packed_proxy_tag> {
|
Chris@16
|
450 typedef packed_proxy_tag storage_category;
|
Chris@16
|
451 };
|
Chris@16
|
452 template<>
|
Chris@16
|
453 struct storage_restrict_traits<packed_tag, sparse_proxy_tag> {
|
Chris@16
|
454 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
455 };
|
Chris@16
|
456
|
Chris@16
|
457 template<>
|
Chris@16
|
458 struct storage_restrict_traits<packed_proxy_tag, sparse_proxy_tag> {
|
Chris@16
|
459 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
460 };
|
Chris@16
|
461
|
Chris@16
|
462 template<>
|
Chris@16
|
463 struct storage_restrict_traits<dense_tag, dense_proxy_tag> {
|
Chris@16
|
464 typedef dense_proxy_tag storage_category;
|
Chris@16
|
465 };
|
Chris@16
|
466 template<>
|
Chris@16
|
467 struct storage_restrict_traits<dense_tag, packed_proxy_tag> {
|
Chris@16
|
468 typedef packed_proxy_tag storage_category;
|
Chris@16
|
469 };
|
Chris@16
|
470 template<>
|
Chris@16
|
471 struct storage_restrict_traits<dense_tag, sparse_proxy_tag> {
|
Chris@16
|
472 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
473 };
|
Chris@16
|
474
|
Chris@16
|
475 template<>
|
Chris@16
|
476 struct storage_restrict_traits<dense_proxy_tag, packed_proxy_tag> {
|
Chris@16
|
477 typedef packed_proxy_tag storage_category;
|
Chris@16
|
478 };
|
Chris@16
|
479 template<>
|
Chris@16
|
480 struct storage_restrict_traits<dense_proxy_tag, sparse_proxy_tag> {
|
Chris@16
|
481 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
482 };
|
Chris@16
|
483
|
Chris@16
|
484
|
Chris@16
|
485 // Iterator tags -- hierarchical definition of storage characteristics
|
Chris@16
|
486
|
Chris@16
|
487 struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {};
|
Chris@16
|
488 struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {};
|
Chris@16
|
489 struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {};
|
Chris@16
|
490
|
Chris@16
|
491 // Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-)
|
Chris@16
|
492 template<class IC>
|
Chris@16
|
493 struct iterator_base_traits {};
|
Chris@16
|
494
|
Chris@16
|
495 template<>
|
Chris@16
|
496 struct iterator_base_traits<std::forward_iterator_tag> {
|
Chris@16
|
497 template<class I, class T>
|
Chris@16
|
498 struct iterator_base {
|
Chris@16
|
499 typedef forward_iterator_base<std::forward_iterator_tag, I, T> type;
|
Chris@16
|
500 };
|
Chris@16
|
501 };
|
Chris@16
|
502
|
Chris@16
|
503 template<>
|
Chris@16
|
504 struct iterator_base_traits<std::bidirectional_iterator_tag> {
|
Chris@16
|
505 template<class I, class T>
|
Chris@16
|
506 struct iterator_base {
|
Chris@16
|
507 typedef bidirectional_iterator_base<std::bidirectional_iterator_tag, I, T> type;
|
Chris@16
|
508 };
|
Chris@16
|
509 };
|
Chris@16
|
510 template<>
|
Chris@16
|
511 struct iterator_base_traits<sparse_bidirectional_iterator_tag> {
|
Chris@16
|
512 template<class I, class T>
|
Chris@16
|
513 struct iterator_base {
|
Chris@16
|
514 typedef bidirectional_iterator_base<sparse_bidirectional_iterator_tag, I, T> type;
|
Chris@16
|
515 };
|
Chris@16
|
516 };
|
Chris@16
|
517
|
Chris@16
|
518 template<>
|
Chris@16
|
519 struct iterator_base_traits<std::random_access_iterator_tag> {
|
Chris@16
|
520 template<class I, class T>
|
Chris@16
|
521 struct iterator_base {
|
Chris@16
|
522 typedef random_access_iterator_base<std::random_access_iterator_tag, I, T> type;
|
Chris@16
|
523 };
|
Chris@16
|
524 };
|
Chris@16
|
525 template<>
|
Chris@16
|
526 struct iterator_base_traits<packed_random_access_iterator_tag> {
|
Chris@16
|
527 template<class I, class T>
|
Chris@16
|
528 struct iterator_base {
|
Chris@16
|
529 typedef random_access_iterator_base<packed_random_access_iterator_tag, I, T> type;
|
Chris@16
|
530 };
|
Chris@16
|
531 };
|
Chris@16
|
532 template<>
|
Chris@16
|
533 struct iterator_base_traits<dense_random_access_iterator_tag> {
|
Chris@16
|
534 template<class I, class T>
|
Chris@16
|
535 struct iterator_base {
|
Chris@16
|
536 typedef random_access_iterator_base<dense_random_access_iterator_tag, I, T> type;
|
Chris@16
|
537 };
|
Chris@16
|
538 };
|
Chris@16
|
539
|
Chris@16
|
540 template<class I1, class I2>
|
Chris@16
|
541 struct iterator_restrict_traits {
|
Chris@16
|
542 typedef I1 iterator_category;
|
Chris@16
|
543 };
|
Chris@16
|
544
|
Chris@16
|
545 template<>
|
Chris@16
|
546 struct iterator_restrict_traits<packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
547 typedef sparse_bidirectional_iterator_tag iterator_category;
|
Chris@16
|
548 };
|
Chris@16
|
549 template<>
|
Chris@16
|
550 struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag> {
|
Chris@16
|
551 typedef sparse_bidirectional_iterator_tag iterator_category;
|
Chris@16
|
552 };
|
Chris@16
|
553
|
Chris@16
|
554 template<>
|
Chris@16
|
555 struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
556 typedef sparse_bidirectional_iterator_tag iterator_category;
|
Chris@16
|
557 };
|
Chris@16
|
558 template<>
|
Chris@16
|
559 struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, dense_random_access_iterator_tag> {
|
Chris@16
|
560 typedef sparse_bidirectional_iterator_tag iterator_category;
|
Chris@16
|
561 };
|
Chris@16
|
562
|
Chris@16
|
563 template<>
|
Chris@16
|
564 struct iterator_restrict_traits<dense_random_access_iterator_tag, packed_random_access_iterator_tag> {
|
Chris@16
|
565 typedef packed_random_access_iterator_tag iterator_category;
|
Chris@16
|
566 };
|
Chris@16
|
567 template<>
|
Chris@16
|
568 struct iterator_restrict_traits<packed_random_access_iterator_tag, dense_random_access_iterator_tag> {
|
Chris@16
|
569 typedef packed_random_access_iterator_tag iterator_category;
|
Chris@16
|
570 };
|
Chris@16
|
571
|
Chris@16
|
572 template<class I>
|
Chris@16
|
573 BOOST_UBLAS_INLINE
|
Chris@16
|
574 void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) {
|
Chris@16
|
575 it += (std::min) (compare, it_end - it);
|
Chris@16
|
576 }
|
Chris@16
|
577 template<class I>
|
Chris@16
|
578 BOOST_UBLAS_INLINE
|
Chris@16
|
579 void increment (I &it, const I &/* it_end */, typename I::difference_type /* compare */, sparse_bidirectional_iterator_tag) {
|
Chris@16
|
580 ++ it;
|
Chris@16
|
581 }
|
Chris@16
|
582 template<class I>
|
Chris@16
|
583 BOOST_UBLAS_INLINE
|
Chris@16
|
584 void increment (I &it, const I &it_end, typename I::difference_type compare) {
|
Chris@16
|
585 increment (it, it_end, compare, typename I::iterator_category ());
|
Chris@16
|
586 }
|
Chris@16
|
587
|
Chris@16
|
588 template<class I>
|
Chris@16
|
589 BOOST_UBLAS_INLINE
|
Chris@16
|
590 void increment (I &it, const I &it_end) {
|
Chris@16
|
591 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
592 I cit (it);
|
Chris@16
|
593 while (cit != it_end) {
|
Chris@16
|
594 BOOST_UBLAS_CHECK (*cit == typename I::value_type/*zero*/(), internal_logic ());
|
Chris@16
|
595 ++ cit;
|
Chris@16
|
596 }
|
Chris@16
|
597 #endif
|
Chris@16
|
598 it = it_end;
|
Chris@16
|
599 }
|
Chris@16
|
600
|
Chris@16
|
601 namespace detail {
|
Chris@16
|
602
|
Chris@16
|
603 // specialisation which define whether a type has a trivial constructor
|
Chris@16
|
604 // or not. This is used by array types.
|
Chris@16
|
605 template<typename T>
|
Chris@16
|
606 struct has_trivial_constructor : public boost::has_trivial_constructor<T> {};
|
Chris@16
|
607
|
Chris@16
|
608 template<typename T>
|
Chris@16
|
609 struct has_trivial_destructor : public boost::has_trivial_destructor<T> {};
|
Chris@16
|
610
|
Chris@16
|
611 template<typename FLT>
|
Chris@16
|
612 struct has_trivial_constructor<std::complex<FLT> > : public has_trivial_constructor<FLT> {};
|
Chris@16
|
613
|
Chris@16
|
614 template<typename FLT>
|
Chris@16
|
615 struct has_trivial_destructor<std::complex<FLT> > : public has_trivial_destructor<FLT> {};
|
Chris@16
|
616
|
Chris@16
|
617 }
|
Chris@16
|
618
|
Chris@16
|
619
|
Chris@16
|
620 /** \brief Traits class to extract type information from a constant matrix or vector CONTAINER.
|
Chris@16
|
621 *
|
Chris@16
|
622 */
|
Chris@16
|
623 template < class E >
|
Chris@16
|
624 struct container_view_traits {
|
Chris@16
|
625 /// type of indices
|
Chris@16
|
626 typedef typename E::size_type size_type;
|
Chris@16
|
627 /// type of differences of indices
|
Chris@16
|
628 typedef typename E::difference_type difference_type;
|
Chris@16
|
629
|
Chris@16
|
630 /// storage category: \c unknown_storage_tag, \c dense_tag, \c packed_tag, ...
|
Chris@16
|
631 typedef typename E::storage_category storage_category;
|
Chris@16
|
632
|
Chris@16
|
633 /// type of elements
|
Chris@16
|
634 typedef typename E::value_type value_type;
|
Chris@16
|
635 /// const reference to an element
|
Chris@16
|
636 typedef typename E::const_reference const_reference;
|
Chris@16
|
637
|
Chris@16
|
638 /// type used in expressions to mark a reference to this class (usually a const container_reference<const E> or the class itself)
|
Chris@16
|
639 typedef typename E::const_closure_type const_closure_type;
|
Chris@16
|
640 };
|
Chris@16
|
641
|
Chris@16
|
642 /** \brief Traits class to extract additional type information from a mutable matrix or vector CONTAINER.
|
Chris@16
|
643 *
|
Chris@16
|
644 */
|
Chris@16
|
645 template < class E >
|
Chris@16
|
646 struct mutable_container_traits {
|
Chris@16
|
647 /// reference to an element
|
Chris@16
|
648 typedef typename E::reference reference;
|
Chris@16
|
649
|
Chris@16
|
650 /// type used in expressions to mark a reference to this class (usually a container_reference<E> or the class itself)
|
Chris@16
|
651 typedef typename E::closure_type closure_type;
|
Chris@16
|
652 };
|
Chris@16
|
653
|
Chris@16
|
654 /** \brief Traits class to extract type information from a matrix or vector CONTAINER.
|
Chris@16
|
655 *
|
Chris@16
|
656 */
|
Chris@16
|
657 template < class E >
|
Chris@16
|
658 struct container_traits
|
Chris@16
|
659 : container_view_traits<E>, mutable_container_traits<E> {
|
Chris@16
|
660
|
Chris@16
|
661 };
|
Chris@16
|
662
|
Chris@16
|
663
|
Chris@16
|
664 /** \brief Traits class to extract type information from a constant MATRIX.
|
Chris@16
|
665 *
|
Chris@16
|
666 */
|
Chris@16
|
667 template < class MATRIX >
|
Chris@16
|
668 struct matrix_view_traits : container_view_traits <MATRIX> {
|
Chris@16
|
669
|
Chris@16
|
670 /// orientation of the matrix, either \c row_major_tag, \c column_major_tag or \c unknown_orientation_tag
|
Chris@16
|
671 typedef typename MATRIX::orientation_category orientation_category;
|
Chris@16
|
672
|
Chris@16
|
673 /// row iterator for the matrix
|
Chris@16
|
674 typedef typename MATRIX::const_iterator1 const_iterator1;
|
Chris@16
|
675
|
Chris@16
|
676 /// column iterator for the matrix
|
Chris@16
|
677 typedef typename MATRIX::const_iterator2 const_iterator2;
|
Chris@16
|
678 };
|
Chris@16
|
679
|
Chris@16
|
680 /** \brief Traits class to extract additional type information from a mutable MATRIX.
|
Chris@16
|
681 *
|
Chris@16
|
682 */
|
Chris@16
|
683 template < class MATRIX >
|
Chris@16
|
684 struct mutable_matrix_traits
|
Chris@16
|
685 : mutable_container_traits <MATRIX> {
|
Chris@16
|
686
|
Chris@16
|
687 /// row iterator for the matrix
|
Chris@16
|
688 typedef typename MATRIX::iterator1 iterator1;
|
Chris@16
|
689
|
Chris@16
|
690 /// column iterator for the matrix
|
Chris@16
|
691 typedef typename MATRIX::iterator2 iterator2;
|
Chris@16
|
692 };
|
Chris@16
|
693
|
Chris@16
|
694
|
Chris@16
|
695 /** \brief Traits class to extract type information from a MATRIX.
|
Chris@16
|
696 *
|
Chris@16
|
697 */
|
Chris@16
|
698 template < class MATRIX >
|
Chris@16
|
699 struct matrix_traits
|
Chris@16
|
700 : matrix_view_traits <MATRIX>, mutable_matrix_traits <MATRIX> {
|
Chris@16
|
701 };
|
Chris@16
|
702
|
Chris@16
|
703 /** \brief Traits class to extract type information from a VECTOR.
|
Chris@16
|
704 *
|
Chris@16
|
705 */
|
Chris@16
|
706 template < class VECTOR >
|
Chris@16
|
707 struct vector_view_traits : container_view_traits <VECTOR> {
|
Chris@16
|
708
|
Chris@16
|
709 /// iterator for the VECTOR
|
Chris@16
|
710 typedef typename VECTOR::const_iterator const_iterator;
|
Chris@16
|
711
|
Chris@16
|
712 /// iterator pointing to the first element
|
Chris@16
|
713 static
|
Chris@16
|
714 const_iterator begin(const VECTOR & v) {
|
Chris@16
|
715 return v.begin();
|
Chris@16
|
716 }
|
Chris@16
|
717 /// iterator pointing behind the last element
|
Chris@16
|
718 static
|
Chris@16
|
719 const_iterator end(const VECTOR & v) {
|
Chris@16
|
720 return v.end();
|
Chris@16
|
721 }
|
Chris@16
|
722
|
Chris@16
|
723 };
|
Chris@16
|
724
|
Chris@16
|
725 /** \brief Traits class to extract type information from a VECTOR.
|
Chris@16
|
726 *
|
Chris@16
|
727 */
|
Chris@16
|
728 template < class VECTOR >
|
Chris@16
|
729 struct mutable_vector_traits : mutable_container_traits <VECTOR> {
|
Chris@16
|
730 /// iterator for the VECTOR
|
Chris@16
|
731 typedef typename VECTOR::iterator iterator;
|
Chris@16
|
732
|
Chris@16
|
733 /// iterator pointing to the first element
|
Chris@16
|
734 static
|
Chris@16
|
735 iterator begin(VECTOR & v) {
|
Chris@16
|
736 return v.begin();
|
Chris@16
|
737 }
|
Chris@16
|
738
|
Chris@16
|
739 /// iterator pointing behind the last element
|
Chris@16
|
740 static
|
Chris@16
|
741 iterator end(VECTOR & v) {
|
Chris@16
|
742 return v.end();
|
Chris@16
|
743 }
|
Chris@16
|
744 };
|
Chris@16
|
745
|
Chris@16
|
746 /** \brief Traits class to extract type information from a VECTOR.
|
Chris@16
|
747 *
|
Chris@16
|
748 */
|
Chris@16
|
749 template < class VECTOR >
|
Chris@16
|
750 struct vector_traits
|
Chris@16
|
751 : vector_view_traits <VECTOR>, mutable_vector_traits <VECTOR> {
|
Chris@16
|
752 };
|
Chris@16
|
753
|
Chris@16
|
754
|
Chris@16
|
755 // Note: specializations for T[N] and T[M][N] have been moved to traits/c_array.hpp
|
Chris@16
|
756
|
Chris@16
|
757 }}}
|
Chris@16
|
758
|
Chris@16
|
759 #endif
|