Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:15

0001 //
0002 //  Copyright (c) 2000-2002
0003 //  Joerg Walter, Mathias Koch
0004 //
0005 //  Distributed under the Boost Software License, Version 1.0. (See
0006 //  accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 //  The authors gratefully acknowledge the support of
0010 //  GeNeSys mbH & Co. KG in producing this work.
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 // anonymous namespace to avoid ADL issues
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     // we'll find either std::sqrt or else another version via ADL:
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         // force a type conversion back to T for char and short types
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     // uBLAS assumes a common return type for all binary arithmetic operators
0152     template<class X, class Y>
0153     struct promote_traits {
0154         typedef BOOST_TYPEOF_TPL(X() + Y()) promote_type;
0155     };
0156 
0157 
0158 
0159     // Type traits - generic numeric properties and functions
0160     template<class T>
0161     struct type_traits;
0162         
0163     // Define properties for a generic scalar type
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;       // we do not know what type has more precision then the real_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 /*t*/) {
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             // force a type conversion back to value_type for intgral types
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     // Define default type traits, assume T is a scalar type
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     // Define real type traits
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     // Define properties for a generic complex type
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;       // we do not know what type has more precision then the real_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             // original computation has been replaced because a complex number should behave like a scalar type
0320             // return type_traits<real_type>::type_abs (self_type::real (t)) +
0321             //       type_traits<real_type>::type_abs (self_type::imag (t));
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             // original computation has been replaced because a complex number should behave like a scalar type
0333             // return (std::max) (type_traits<real_type>::type_abs (self_type::real (t)),
0334             //                 type_traits<real_type>::type_abs (self_type::imag (t)));
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     // Define complex type traits
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     // Define scalar interval type traits
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     // Storage tags -- hierarchical definition of storage characteristics
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     // Iterator tags -- hierarchical definition of storage characteristics
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     // Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-)
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 &/* it_end */, typename I::difference_type /* compare */, 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/*zero*/(), internal_logic ());
0589             ++ cit;
0590         }
0591 #endif
0592         it = it_end;
0593     }
0594 
0595     namespace detail {
0596 
0597         // specialisation which define whether a type has a trivial constructor
0598         // or not. This is used by array types.
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     /**  \brief Traits class to extract type information from a constant matrix or vector CONTAINER.
0615      *
0616      */
0617     template < class E >
0618     struct container_view_traits {
0619         /// type of indices
0620         typedef typename E::size_type             size_type;
0621         /// type of differences of indices
0622         typedef typename E::difference_type       difference_type;
0623 
0624         /// storage category: \c unknown_storage_tag, \c dense_tag, \c packed_tag, ...
0625         typedef typename E::storage_category      storage_category;
0626 
0627         /// type of elements
0628         typedef typename E::value_type            value_type;
0629         /// const reference to an element
0630         typedef typename E::const_reference       const_reference;
0631   
0632         /// type used in expressions to mark a reference to this class (usually a const container_reference<const E> or the class itself)
0633         typedef typename E::const_closure_type    const_closure_type;
0634     };
0635 
0636     /**  \brief Traits class to extract additional type information from a mutable matrix or vector CONTAINER.
0637      *
0638      */
0639     template < class E >
0640     struct mutable_container_traits {
0641         /// reference to an element
0642         typedef typename E::reference             reference;
0643   
0644         /// type used in expressions to mark a reference to this class (usually a container_reference<E> or the class itself)
0645         typedef typename E::closure_type          closure_type;
0646     };
0647 
0648     /**  \brief Traits class to extract type information from a matrix or vector CONTAINER.
0649      *
0650      */
0651     template < class E >
0652     struct container_traits 
0653         : container_view_traits<E>, mutable_container_traits<E> {
0654 
0655     };
0656 
0657 
0658     /**  \brief Traits class to extract type information from a constant MATRIX.
0659      *
0660      */
0661     template < class MATRIX >
0662     struct matrix_view_traits : container_view_traits <MATRIX> {
0663 
0664         /// orientation of the matrix, either \c row_major_tag, \c column_major_tag or \c unknown_orientation_tag
0665         typedef typename MATRIX::orientation_category  orientation_category;
0666   
0667         /// row iterator for the matrix
0668         typedef typename MATRIX::const_iterator1  const_iterator1;
0669 
0670         /// column iterator for the matrix
0671         typedef typename MATRIX::const_iterator2  const_iterator2;
0672     };
0673 
0674     /**  \brief Traits class to extract additional type information from a mutable MATRIX.
0675      *
0676      */
0677     template < class MATRIX >
0678     struct mutable_matrix_traits 
0679         : mutable_container_traits <MATRIX> {
0680 
0681         /// row iterator for the matrix
0682         typedef typename MATRIX::iterator1  iterator1;
0683 
0684         /// column iterator for the matrix
0685         typedef typename MATRIX::iterator2  iterator2;
0686     };
0687 
0688 
0689     /**  \brief Traits class to extract type information from a MATRIX.
0690      *
0691      */
0692     template < class MATRIX >
0693     struct matrix_traits 
0694         : matrix_view_traits <MATRIX>, mutable_matrix_traits <MATRIX> {
0695     };
0696 
0697     /**  \brief Traits class to extract type information from a VECTOR.
0698      *
0699      */
0700     template < class VECTOR >
0701     struct vector_view_traits : container_view_traits <VECTOR> {
0702 
0703         /// iterator for the VECTOR
0704         typedef typename VECTOR::const_iterator  const_iterator;
0705 
0706         /// iterator pointing to the first element
0707         static
0708         const_iterator begin(const VECTOR & v) {
0709             return v.begin();
0710         }
0711         /// iterator pointing behind the last element
0712         static
0713         const_iterator end(const VECTOR & v) {
0714             return v.end();
0715         }
0716 
0717     };
0718 
0719     /**  \brief Traits class to extract type information from a VECTOR.
0720      *
0721      */
0722     template < class VECTOR >
0723     struct mutable_vector_traits : mutable_container_traits <VECTOR> {
0724         /// iterator for the VECTOR
0725         typedef typename VECTOR::iterator  iterator;
0726 
0727         /// iterator pointing to the first element
0728         static
0729         iterator begin(VECTOR & v) {
0730             return v.begin();
0731         }
0732 
0733         /// iterator pointing behind the last element
0734         static
0735         iterator end(VECTOR & v) {
0736             return v.end();
0737         }
0738     };
0739 
0740     /**  \brief Traits class to extract type information from a VECTOR.
0741      *
0742      */
0743     template < class VECTOR >
0744     struct vector_traits 
0745         : vector_view_traits <VECTOR>, mutable_vector_traits <VECTOR> {
0746     };
0747 
0748 
0749     // Note: specializations for T[N] and T[M][N] have been moved to traits/c_array.hpp
0750 
0751 }}}
0752 
0753 #endif