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