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