File indexing completed on 2025-01-18 09:43:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef _BOOST_UBLAS_TRAITS_
0014 #define _BOOST_UBLAS_TRAITS_
0015
0016 #include <iterator>
0017 #include <complex>
0018 #include <boost/config/no_tr1/cmath.hpp>
0019
0020 #include <boost/numeric/ublas/detail/config.hpp>
0021 #include <boost/numeric/ublas/detail/iterator.hpp>
0022 #include <boost/numeric/ublas/detail/returntype_deduction.hpp>
0023 #ifdef BOOST_UBLAS_USE_INTERVAL
0024 #include <boost/numeric/interval.hpp>
0025 #endif
0026
0027 #include <boost/type_traits.hpp>
0028 #include <complex>
0029 #include <boost/typeof/typeof.hpp>
0030 #include <boost/utility/enable_if.hpp>
0031 #include <boost/type_traits/is_float.hpp>
0032 #include <boost/type_traits/is_integral.hpp>
0033 #include <boost/type_traits/is_unsigned.hpp>
0034 #include <boost/mpl/and.hpp>
0035 #include <boost/mpl/if.hpp>
0036 #include <boost/typeof/typeof.hpp>
0037
0038
0039
0040 namespace {
0041 template<class T>
0042 typename boost::mpl::if_c<boost::is_integral<T>::value,
0043 double,
0044 T>::type
0045 boost_numeric_ublas_sqrt (const T& t) {
0046 using namespace std;
0047
0048 return sqrt (t);
0049 }
0050
0051 template<typename T>
0052 inline typename boost::disable_if<
0053 boost::is_unsigned<T>, T >::type
0054 boost_numeric_ublas_abs (const T &t ) {
0055 using namespace std;
0056
0057 return static_cast<T>(abs( t ));
0058 }
0059
0060 template<typename T>
0061 inline typename boost::enable_if<
0062 boost::is_unsigned<T>, T >::type
0063 boost_numeric_ublas_abs (const T &t ) {
0064 return t;
0065 }
0066 }
0067
0068 namespace boost { namespace numeric { namespace ublas {
0069
0070
0071 template<typename R, typename I>
0072 typename boost::enable_if<
0073 mpl::and_<
0074 boost::is_float<R>,
0075 boost::is_integral<I>
0076 >,
0077 std::complex<R> >::type inline operator+ (I in1, std::complex<R> const& in2 ) {
0078 return R (in1) + in2;
0079 }
0080
0081 template<typename R, typename I>
0082 typename boost::enable_if<
0083 mpl::and_<
0084 boost::is_float<R>,
0085 boost::is_integral<I>
0086 >,
0087 std::complex<R> >::type inline operator+ (std::complex<R> const& in1, I in2) {
0088 return in1 + R (in2);
0089 }
0090
0091 template<typename R, typename I>
0092 typename boost::enable_if<
0093 mpl::and_<
0094 boost::is_float<R>,
0095 boost::is_integral<I>
0096 >,
0097 std::complex<R> >::type inline operator- (I in1, std::complex<R> const& in2) {
0098 return R (in1) - in2;
0099 }
0100
0101 template<typename R, typename I>
0102 typename boost::enable_if<
0103 mpl::and_<
0104 boost::is_float<R>,
0105 boost::is_integral<I>
0106 >,
0107 std::complex<R> >::type inline operator- (std::complex<R> const& in1, I in2) {
0108 return in1 - R (in2);
0109 }
0110
0111 template<typename R, typename I>
0112 typename boost::enable_if<
0113 mpl::and_<
0114 boost::is_float<R>,
0115 boost::is_integral<I>
0116 >,
0117 std::complex<R> >::type inline operator* (I in1, std::complex<R> const& in2) {
0118 return R (in1) * in2;
0119 }
0120
0121 template<typename R, typename I>
0122 typename boost::enable_if<
0123 mpl::and_<
0124 boost::is_float<R>,
0125 boost::is_integral<I>
0126 >,
0127 std::complex<R> >::type inline operator* (std::complex<R> const& in1, I in2) {
0128 return in1 * R(in2);
0129 }
0130
0131 template<typename R, typename I>
0132 typename boost::enable_if<
0133 mpl::and_<
0134 boost::is_float<R>,
0135 boost::is_integral<I>
0136 >,
0137 std::complex<R> >::type inline operator/ (I in1, std::complex<R> const& in2) {
0138 return R(in1) / in2;
0139 }
0140
0141 template<typename R, typename I>
0142 typename boost::enable_if<
0143 mpl::and_<
0144 boost::is_float<R>,
0145 boost::is_integral<I>
0146 >,
0147 std::complex<R> >::type inline operator/ (std::complex<R> const& in1, I in2) {
0148 return in1 / R (in2);
0149 }
0150
0151
0152 template<class X, class Y>
0153 struct promote_traits {
0154 typedef BOOST_TYPEOF_TPL(X() + Y()) promote_type;
0155 };
0156
0157
0158
0159
0160 template<class T>
0161 struct type_traits;
0162
0163
0164 template<class T>
0165 struct scalar_traits {
0166 typedef scalar_traits<T> self_type;
0167 typedef T value_type;
0168 typedef const T &const_reference;
0169 typedef T &reference;
0170
0171 typedef T real_type;
0172 typedef real_type precision_type;
0173
0174 static const unsigned plus_complexity = 1;
0175 static const unsigned multiplies_complexity = 1;
0176
0177 static
0178 BOOST_UBLAS_INLINE
0179 real_type real (const_reference t) {
0180 return t;
0181 }
0182 static
0183 BOOST_UBLAS_INLINE
0184 real_type imag (const_reference ) {
0185 return 0;
0186 }
0187 static
0188 BOOST_UBLAS_INLINE
0189 value_type conj (const_reference t) {
0190 return t;
0191 }
0192
0193 static
0194 BOOST_UBLAS_INLINE
0195 real_type type_abs (const_reference t) {
0196 return boost_numeric_ublas_abs (t);
0197 }
0198 static
0199 BOOST_UBLAS_INLINE
0200 value_type type_sqrt (const_reference t) {
0201
0202 return value_type (boost_numeric_ublas_sqrt (t));
0203 }
0204
0205 static
0206 BOOST_UBLAS_INLINE
0207 real_type norm_1 (const_reference t) {
0208 return self_type::type_abs (t);
0209 }
0210 static
0211 BOOST_UBLAS_INLINE
0212 real_type norm_2 (const_reference t) {
0213 return self_type::type_abs (t);
0214 }
0215 static
0216 BOOST_UBLAS_INLINE
0217 real_type norm_inf (const_reference t) {
0218 return self_type::type_abs (t);
0219 }
0220
0221 static
0222 BOOST_UBLAS_INLINE
0223 bool equals (const_reference t1, const_reference t2) {
0224 return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
0225 (std::max) ((std::max) (self_type::norm_inf (t1),
0226 self_type::norm_inf (t2)),
0227 BOOST_UBLAS_TYPE_CHECK_MIN);
0228 }
0229 };
0230
0231
0232 template<class T>
0233 struct type_traits : scalar_traits <T> {
0234 typedef type_traits<T> self_type;
0235 typedef T value_type;
0236 typedef const T &const_reference;
0237 typedef T &reference;
0238
0239 typedef T real_type;
0240 typedef real_type precision_type;
0241 static const unsigned multiplies_complexity = 1;
0242
0243 };
0244
0245
0246 template<>
0247 struct type_traits<float> : scalar_traits<float> {
0248 typedef type_traits<float> self_type;
0249 typedef float value_type;
0250 typedef const value_type &const_reference;
0251 typedef value_type &reference;
0252 typedef value_type real_type;
0253 typedef double precision_type;
0254 };
0255 template<>
0256 struct type_traits<double> : scalar_traits<double> {
0257 typedef type_traits<double> self_type;
0258 typedef double value_type;
0259 typedef const value_type &const_reference;
0260 typedef value_type &reference;
0261 typedef value_type real_type;
0262 typedef long double precision_type;
0263 };
0264 template<>
0265 struct type_traits<long double> : scalar_traits<long double> {
0266 typedef type_traits<long double> self_type;
0267 typedef long double value_type;
0268 typedef const value_type &const_reference;
0269 typedef value_type &reference;
0270 typedef value_type real_type;
0271 typedef value_type precision_type;
0272 };
0273
0274
0275 template<class T>
0276 struct complex_traits {
0277 typedef complex_traits<T> self_type;
0278 typedef T value_type;
0279 typedef const T &const_reference;
0280 typedef T &reference;
0281
0282 typedef typename T::value_type real_type;
0283 typedef real_type precision_type;
0284
0285 static const unsigned plus_complexity = 2;
0286 static const unsigned multiplies_complexity = 6;
0287
0288 static
0289 BOOST_UBLAS_INLINE
0290 real_type real (const_reference t) {
0291 return std::real (t);
0292 }
0293 static
0294 BOOST_UBLAS_INLINE
0295 real_type imag (const_reference t) {
0296 return std::imag (t);
0297 }
0298 static
0299 BOOST_UBLAS_INLINE
0300 value_type conj (const_reference t) {
0301 return std::conj (t);
0302 }
0303
0304 static
0305 BOOST_UBLAS_INLINE
0306 real_type type_abs (const_reference t) {
0307 return abs (t);
0308 }
0309 static
0310 BOOST_UBLAS_INLINE
0311 value_type type_sqrt (const_reference t) {
0312 return sqrt (t);
0313 }
0314
0315 static
0316 BOOST_UBLAS_INLINE
0317 real_type norm_1 (const_reference t) {
0318 return self_type::type_abs (t);
0319
0320
0321
0322 }
0323 static
0324 BOOST_UBLAS_INLINE
0325 real_type norm_2 (const_reference t) {
0326 return self_type::type_abs (t);
0327 }
0328 static
0329 BOOST_UBLAS_INLINE
0330 real_type norm_inf (const_reference t) {
0331 return self_type::type_abs (t);
0332
0333
0334
0335 }
0336
0337 static
0338 BOOST_UBLAS_INLINE
0339 bool equals (const_reference t1, const_reference t2) {
0340 return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
0341 (std::max) ((std::max) (self_type::norm_inf (t1),
0342 self_type::norm_inf (t2)),
0343 BOOST_UBLAS_TYPE_CHECK_MIN);
0344 }
0345 };
0346
0347
0348 template<>
0349 struct type_traits<std::complex<float> > : complex_traits<std::complex<float> >{
0350 typedef type_traits<std::complex<float> > self_type;
0351 typedef std::complex<float> value_type;
0352 typedef const value_type &const_reference;
0353 typedef value_type &reference;
0354 typedef float real_type;
0355 typedef std::complex<double> precision_type;
0356
0357 };
0358 template<>
0359 struct type_traits<std::complex<double> > : complex_traits<std::complex<double> >{
0360 typedef type_traits<std::complex<double> > self_type;
0361 typedef std::complex<double> value_type;
0362 typedef const value_type &const_reference;
0363 typedef value_type &reference;
0364 typedef double real_type;
0365 typedef std::complex<long double> precision_type;
0366 };
0367 template<>
0368 struct type_traits<std::complex<long double> > : complex_traits<std::complex<long double> > {
0369 typedef type_traits<std::complex<long double> > self_type;
0370 typedef std::complex<long double> value_type;
0371 typedef const value_type &const_reference;
0372 typedef value_type &reference;
0373 typedef long double real_type;
0374 typedef value_type precision_type;
0375 };
0376
0377 #ifdef BOOST_UBLAS_USE_INTERVAL
0378
0379 template<>
0380 struct type_traits<boost::numeric::interval<float> > : scalar_traits<boost::numeric::interval<float> > {
0381 typedef type_traits<boost::numeric::interval<float> > self_type;
0382 typedef boost::numeric::interval<float> value_type;
0383 typedef const value_type &const_reference;
0384 typedef value_type &reference;
0385 typedef value_type real_type;
0386 typedef boost::numeric::interval<double> precision_type;
0387
0388 };
0389 template<>
0390 struct type_traits<boost::numeric::interval<double> > : scalar_traits<boost::numeric::interval<double> > {
0391 typedef type_traits<boost::numeric::interval<double> > self_type;
0392 typedef boost::numeric::interval<double> value_type;
0393 typedef const value_type &const_reference;
0394 typedef value_type &reference;
0395 typedef value_type real_type;
0396 typedef boost::numeric::interval<long double> precision_type;
0397 };
0398 template<>
0399 struct type_traits<boost::numeric::interval<long double> > : scalar_traits<boost::numeric::interval<long double> > {
0400 typedef type_traits<boost::numeric::interval<long double> > self_type;
0401 typedef boost::numeric::interval<long double> value_type;
0402 typedef const value_type &const_reference;
0403 typedef value_type &reference;
0404 typedef value_type real_type;
0405 typedef value_type precision_type;
0406 };
0407 #endif
0408
0409
0410
0411
0412 struct unknown_storage_tag {};
0413 struct sparse_proxy_tag: public unknown_storage_tag {};
0414 struct sparse_tag: public sparse_proxy_tag {};
0415 struct packed_proxy_tag: public sparse_proxy_tag {};
0416 struct packed_tag: public packed_proxy_tag {};
0417 struct dense_proxy_tag: public packed_proxy_tag {};
0418 struct dense_tag: public dense_proxy_tag {};
0419
0420 template<class S1, class S2>
0421 struct storage_restrict_traits {
0422 typedef S1 storage_category;
0423 };
0424
0425 template<>
0426 struct storage_restrict_traits<sparse_tag, dense_proxy_tag> {
0427 typedef sparse_proxy_tag storage_category;
0428 };
0429 template<>
0430 struct storage_restrict_traits<sparse_tag, packed_proxy_tag> {
0431 typedef sparse_proxy_tag storage_category;
0432 };
0433 template<>
0434 struct storage_restrict_traits<sparse_tag, sparse_proxy_tag> {
0435 typedef sparse_proxy_tag storage_category;
0436 };
0437
0438 template<>
0439 struct storage_restrict_traits<packed_tag, dense_proxy_tag> {
0440 typedef packed_proxy_tag storage_category;
0441 };
0442 template<>
0443 struct storage_restrict_traits<packed_tag, packed_proxy_tag> {
0444 typedef packed_proxy_tag storage_category;
0445 };
0446 template<>
0447 struct storage_restrict_traits<packed_tag, sparse_proxy_tag> {
0448 typedef sparse_proxy_tag storage_category;
0449 };
0450
0451 template<>
0452 struct storage_restrict_traits<packed_proxy_tag, sparse_proxy_tag> {
0453 typedef sparse_proxy_tag storage_category;
0454 };
0455
0456 template<>
0457 struct storage_restrict_traits<dense_tag, dense_proxy_tag> {
0458 typedef dense_proxy_tag storage_category;
0459 };
0460 template<>
0461 struct storage_restrict_traits<dense_tag, packed_proxy_tag> {
0462 typedef packed_proxy_tag storage_category;
0463 };
0464 template<>
0465 struct storage_restrict_traits<dense_tag, sparse_proxy_tag> {
0466 typedef sparse_proxy_tag storage_category;
0467 };
0468
0469 template<>
0470 struct storage_restrict_traits<dense_proxy_tag, packed_proxy_tag> {
0471 typedef packed_proxy_tag storage_category;
0472 };
0473 template<>
0474 struct storage_restrict_traits<dense_proxy_tag, sparse_proxy_tag> {
0475 typedef sparse_proxy_tag storage_category;
0476 };
0477
0478
0479
0480
0481 struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {};
0482 struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {};
0483 struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {};
0484
0485
0486 template<class IC>
0487 struct iterator_base_traits {};
0488
0489 template<>
0490 struct iterator_base_traits<std::forward_iterator_tag> {
0491 template<class I, class T>
0492 struct iterator_base {
0493 typedef forward_iterator_base<std::forward_iterator_tag, I, T> type;
0494 };
0495 };
0496
0497 template<>
0498 struct iterator_base_traits<std::bidirectional_iterator_tag> {
0499 template<class I, class T>
0500 struct iterator_base {
0501 typedef bidirectional_iterator_base<std::bidirectional_iterator_tag, I, T> type;
0502 };
0503 };
0504 template<>
0505 struct iterator_base_traits<sparse_bidirectional_iterator_tag> {
0506 template<class I, class T>
0507 struct iterator_base {
0508 typedef bidirectional_iterator_base<sparse_bidirectional_iterator_tag, I, T> type;
0509 };
0510 };
0511
0512 template<>
0513 struct iterator_base_traits<std::random_access_iterator_tag> {
0514 template<class I, class T>
0515 struct iterator_base {
0516 typedef random_access_iterator_base<std::random_access_iterator_tag, I, T> type;
0517 };
0518 };
0519 template<>
0520 struct iterator_base_traits<packed_random_access_iterator_tag> {
0521 template<class I, class T>
0522 struct iterator_base {
0523 typedef random_access_iterator_base<packed_random_access_iterator_tag, I, T> type;
0524 };
0525 };
0526 template<>
0527 struct iterator_base_traits<dense_random_access_iterator_tag> {
0528 template<class I, class T>
0529 struct iterator_base {
0530 typedef random_access_iterator_base<dense_random_access_iterator_tag, I, T> type;
0531 };
0532 };
0533
0534 template<class I1, class I2>
0535 struct iterator_restrict_traits {
0536 typedef I1 iterator_category;
0537 };
0538
0539 template<>
0540 struct iterator_restrict_traits<packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
0541 typedef sparse_bidirectional_iterator_tag iterator_category;
0542 };
0543 template<>
0544 struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag> {
0545 typedef sparse_bidirectional_iterator_tag iterator_category;
0546 };
0547
0548 template<>
0549 struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
0550 typedef sparse_bidirectional_iterator_tag iterator_category;
0551 };
0552 template<>
0553 struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, dense_random_access_iterator_tag> {
0554 typedef sparse_bidirectional_iterator_tag iterator_category;
0555 };
0556
0557 template<>
0558 struct iterator_restrict_traits<dense_random_access_iterator_tag, packed_random_access_iterator_tag> {
0559 typedef packed_random_access_iterator_tag iterator_category;
0560 };
0561 template<>
0562 struct iterator_restrict_traits<packed_random_access_iterator_tag, dense_random_access_iterator_tag> {
0563 typedef packed_random_access_iterator_tag iterator_category;
0564 };
0565
0566 template<class I>
0567 BOOST_UBLAS_INLINE
0568 void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) {
0569 it += (std::min) (compare, it_end - it);
0570 }
0571 template<class I>
0572 BOOST_UBLAS_INLINE
0573 void increment (I &it, const I &, typename I::difference_type , sparse_bidirectional_iterator_tag) {
0574 ++ it;
0575 }
0576 template<class I>
0577 BOOST_UBLAS_INLINE
0578 void increment (I &it, const I &it_end, typename I::difference_type compare) {
0579 increment (it, it_end, compare, typename I::iterator_category ());
0580 }
0581
0582 template<class I>
0583 BOOST_UBLAS_INLINE
0584 void increment (I &it, const I &it_end) {
0585 #if BOOST_UBLAS_TYPE_CHECK
0586 I cit (it);
0587 while (cit != it_end) {
0588 BOOST_UBLAS_CHECK (*cit == typename I::value_type(), internal_logic ());
0589 ++ cit;
0590 }
0591 #endif
0592 it = it_end;
0593 }
0594
0595 namespace detail {
0596
0597
0598
0599 template<typename T>
0600 struct has_trivial_constructor : public boost::has_trivial_constructor<T> {};
0601
0602 template<typename T>
0603 struct has_trivial_destructor : public boost::has_trivial_destructor<T> {};
0604
0605 template<typename FLT>
0606 struct has_trivial_constructor<std::complex<FLT> > : public has_trivial_constructor<FLT> {};
0607
0608 template<typename FLT>
0609 struct has_trivial_destructor<std::complex<FLT> > : public has_trivial_destructor<FLT> {};
0610
0611 }
0612
0613
0614
0615
0616
0617 template < class E >
0618 struct container_view_traits {
0619
0620 typedef typename E::size_type size_type;
0621
0622 typedef typename E::difference_type difference_type;
0623
0624
0625 typedef typename E::storage_category storage_category;
0626
0627
0628 typedef typename E::value_type value_type;
0629
0630 typedef typename E::const_reference const_reference;
0631
0632
0633 typedef typename E::const_closure_type const_closure_type;
0634 };
0635
0636
0637
0638
0639 template < class E >
0640 struct mutable_container_traits {
0641
0642 typedef typename E::reference reference;
0643
0644
0645 typedef typename E::closure_type closure_type;
0646 };
0647
0648
0649
0650
0651 template < class E >
0652 struct container_traits
0653 : container_view_traits<E>, mutable_container_traits<E> {
0654
0655 };
0656
0657
0658
0659
0660
0661 template < class MATRIX >
0662 struct matrix_view_traits : container_view_traits <MATRIX> {
0663
0664
0665 typedef typename MATRIX::orientation_category orientation_category;
0666
0667
0668 typedef typename MATRIX::const_iterator1 const_iterator1;
0669
0670
0671 typedef typename MATRIX::const_iterator2 const_iterator2;
0672 };
0673
0674
0675
0676
0677 template < class MATRIX >
0678 struct mutable_matrix_traits
0679 : mutable_container_traits <MATRIX> {
0680
0681
0682 typedef typename MATRIX::iterator1 iterator1;
0683
0684
0685 typedef typename MATRIX::iterator2 iterator2;
0686 };
0687
0688
0689
0690
0691
0692 template < class MATRIX >
0693 struct matrix_traits
0694 : matrix_view_traits <MATRIX>, mutable_matrix_traits <MATRIX> {
0695 };
0696
0697
0698
0699
0700 template < class VECTOR >
0701 struct vector_view_traits : container_view_traits <VECTOR> {
0702
0703
0704 typedef typename VECTOR::const_iterator const_iterator;
0705
0706
0707 static
0708 const_iterator begin(const VECTOR & v) {
0709 return v.begin();
0710 }
0711
0712 static
0713 const_iterator end(const VECTOR & v) {
0714 return v.end();
0715 }
0716
0717 };
0718
0719
0720
0721
0722 template < class VECTOR >
0723 struct mutable_vector_traits : mutable_container_traits <VECTOR> {
0724
0725 typedef typename VECTOR::iterator iterator;
0726
0727
0728 static
0729 iterator begin(VECTOR & v) {
0730 return v.begin();
0731 }
0732
0733
0734 static
0735 iterator end(VECTOR & v) {
0736 return v.end();
0737 }
0738 };
0739
0740
0741
0742
0743 template < class VECTOR >
0744 struct vector_traits
0745 : vector_view_traits <VECTOR>, mutable_vector_traits <VECTOR> {
0746 };
0747
0748
0749
0750
0751 }}}
0752
0753 #endif