Chris@16: // Chris@16: // Copyright (c) 2000-2002 Chris@16: // Joerg Walter, Mathias Koch Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // The authors gratefully acknowledge the support of Chris@16: // GeNeSys mbH & Co. KG in producing this work. Chris@16: // Chris@16: Chris@16: #ifndef _BOOST_UBLAS_TRAITS_ Chris@16: #define _BOOST_UBLAS_TRAITS_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #ifdef BOOST_UBLAS_USE_INTERVAL Chris@101: #include Chris@101: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: Chris@16: // anonymous namespace to avoid ADL issues Chris@16: namespace { Chris@16: template T boost_numeric_ublas_sqrt (const T& t) { Chris@16: using namespace std; Chris@16: // we'll find either std::sqrt or else another version via ADL: Chris@16: return sqrt (t); Chris@16: } Chris@101: Chris@101: template Chris@101: inline typename boost::disable_if< Chris@101: boost::is_unsigned, T >::type Chris@101: boost_numeric_ublas_abs (const T &t ) { Chris@101: using namespace std; Chris@101: return abs( t ); Chris@101: } Chris@101: Chris@101: template Chris@101: inline typename boost::enable_if< Chris@101: boost::is_unsigned, T >::type Chris@101: boost_numeric_ublas_abs (const T &t ) { Chris@101: return t; Chris@101: } Chris@16: } Chris@16: Chris@16: namespace boost { namespace numeric { namespace ublas { Chris@16: Chris@101: Chris@101: template Chris@101: typename boost::enable_if< Chris@101: mpl::and_< Chris@101: boost::is_float, Chris@101: boost::is_integral Chris@101: >, Chris@101: std::complex >::type inline operator+ (I in1, std::complex const& in2 ) { Chris@101: return R (in1) + in2; Chris@101: } Chris@101: Chris@101: template Chris@101: typename boost::enable_if< Chris@101: mpl::and_< Chris@101: boost::is_float, Chris@101: boost::is_integral Chris@101: >, Chris@101: std::complex >::type inline operator+ (std::complex const& in1, I in2) { Chris@101: return in1 + R (in2); Chris@101: } Chris@101: Chris@101: template Chris@101: typename boost::enable_if< Chris@101: mpl::and_< Chris@101: boost::is_float, Chris@101: boost::is_integral Chris@101: >, Chris@101: std::complex >::type inline operator- (I in1, std::complex const& in2) { Chris@101: return R (in1) - in2; Chris@101: } Chris@101: Chris@101: template Chris@101: typename boost::enable_if< Chris@101: mpl::and_< Chris@101: boost::is_float, Chris@101: boost::is_integral Chris@101: >, Chris@101: std::complex >::type inline operator- (std::complex const& in1, I in2) { Chris@101: return in1 - R (in2); Chris@101: } Chris@101: Chris@101: template Chris@101: typename boost::enable_if< Chris@101: mpl::and_< Chris@101: boost::is_float, Chris@101: boost::is_integral Chris@101: >, Chris@101: std::complex >::type inline operator* (I in1, std::complex const& in2) { Chris@101: return R (in1) * in2; Chris@101: } Chris@101: Chris@101: template Chris@101: typename boost::enable_if< Chris@101: mpl::and_< Chris@101: boost::is_float, Chris@101: boost::is_integral Chris@101: >, Chris@101: std::complex >::type inline operator* (std::complex const& in1, I in2) { Chris@101: return in1 * R(in2); Chris@101: } Chris@101: Chris@101: template Chris@101: typename boost::enable_if< Chris@101: mpl::and_< Chris@101: boost::is_float, Chris@101: boost::is_integral Chris@101: >, Chris@101: std::complex >::type inline operator/ (I in1, std::complex const& in2) { Chris@101: return R(in1) / in2; Chris@101: } Chris@101: Chris@101: template Chris@101: typename boost::enable_if< Chris@101: mpl::and_< Chris@101: boost::is_float, Chris@101: boost::is_integral Chris@101: >, Chris@101: std::complex >::type inline operator/ (std::complex const& in1, I in2) { Chris@101: return in1 / R (in2); Chris@101: } Chris@101: Chris@16: // Use Joel de Guzman's return type deduction Chris@16: // uBLAS assumes a common return type for all binary arithmetic operators Chris@16: template Chris@16: struct promote_traits { Chris@16: typedef type_deduction_detail::base_result_of base_type; Chris@16: static typename base_type::x_type x; Chris@16: static typename base_type::y_type y; Chris@16: static const std::size_t size = sizeof ( Chris@16: type_deduction_detail::test< Chris@16: typename base_type::x_type Chris@16: , typename base_type::y_type Chris@16: >(x + y) // Use x+y to stand of all the arithmetic actions Chris@16: ); Chris@16: Chris@16: static const std::size_t index = (size / sizeof (char)) - 1; Chris@16: typedef typename mpl::at_c< Chris@16: typename base_type::types, index>::type id; Chris@16: typedef typename id::type promote_type; Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: // Type traits - generic numeric properties and functions Chris@16: template Chris@16: struct type_traits; Chris@16: Chris@16: // Define properties for a generic scalar type Chris@16: template Chris@16: struct scalar_traits { Chris@16: typedef scalar_traits self_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: Chris@16: typedef T real_type; Chris@16: typedef real_type precision_type; // we do not know what type has more precision then the real_type Chris@16: Chris@16: static const unsigned plus_complexity = 1; Chris@16: static const unsigned multiplies_complexity = 1; Chris@16: Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type real (const_reference t) { Chris@16: return t; Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type imag (const_reference /*t*/) { Chris@16: return 0; Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type conj (const_reference t) { Chris@16: return t; Chris@16: } Chris@16: Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type type_abs (const_reference t) { Chris@16: return boost_numeric_ublas_abs (t); Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type type_sqrt (const_reference t) { Chris@16: // force a type conversion back to value_type for intgral types Chris@16: return value_type (boost_numeric_ublas_sqrt (t)); Chris@16: } Chris@16: Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type norm_1 (const_reference t) { Chris@16: return self_type::type_abs (t); Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type norm_2 (const_reference t) { Chris@16: return self_type::type_abs (t); Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type norm_inf (const_reference t) { Chris@16: return self_type::type_abs (t); Chris@16: } Chris@16: Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: bool equals (const_reference t1, const_reference t2) { Chris@16: return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON * Chris@16: (std::max) ((std::max) (self_type::norm_inf (t1), Chris@16: self_type::norm_inf (t2)), Chris@16: BOOST_UBLAS_TYPE_CHECK_MIN); Chris@16: } Chris@16: }; Chris@16: Chris@16: // Define default type traits, assume T is a scalar type Chris@16: template Chris@16: struct type_traits : scalar_traits { Chris@16: typedef type_traits self_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: Chris@16: typedef T real_type; Chris@16: typedef real_type precision_type; Chris@16: static const unsigned multiplies_complexity = 1; Chris@16: Chris@16: }; Chris@16: Chris@16: // Define real type traits Chris@16: template<> Chris@16: struct type_traits : scalar_traits { Chris@16: typedef type_traits self_type; Chris@16: typedef float value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef value_type real_type; Chris@16: typedef double precision_type; Chris@16: }; Chris@16: template<> Chris@16: struct type_traits : scalar_traits { Chris@16: typedef type_traits self_type; Chris@16: typedef double value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef value_type real_type; Chris@16: typedef long double precision_type; Chris@16: }; Chris@16: template<> Chris@16: struct type_traits : scalar_traits { Chris@16: typedef type_traits self_type; Chris@16: typedef long double value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef value_type real_type; Chris@16: typedef value_type precision_type; Chris@16: }; Chris@16: Chris@16: // Define properties for a generic complex type Chris@16: template Chris@16: struct complex_traits { Chris@16: typedef complex_traits self_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: Chris@16: typedef typename T::value_type real_type; Chris@16: typedef real_type precision_type; // we do not know what type has more precision then the real_type Chris@16: Chris@16: static const unsigned plus_complexity = 2; Chris@16: static const unsigned multiplies_complexity = 6; Chris@16: Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type real (const_reference t) { Chris@16: return std::real (t); Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type imag (const_reference t) { Chris@16: return std::imag (t); Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type conj (const_reference t) { Chris@16: return std::conj (t); Chris@16: } Chris@16: Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type type_abs (const_reference t) { Chris@16: return abs (t); Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type type_sqrt (const_reference t) { Chris@16: return sqrt (t); Chris@16: } Chris@16: Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type norm_1 (const_reference t) { Chris@16: return self_type::type_abs (t); Chris@16: // original computation has been replaced because a complex number should behave like a scalar type Chris@16: // return type_traits::type_abs (self_type::real (t)) + Chris@16: // type_traits::type_abs (self_type::imag (t)); Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type norm_2 (const_reference t) { Chris@16: return self_type::type_abs (t); Chris@16: } Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: real_type norm_inf (const_reference t) { Chris@16: return self_type::type_abs (t); Chris@16: // original computation has been replaced because a complex number should behave like a scalar type Chris@16: // return (std::max) (type_traits::type_abs (self_type::real (t)), Chris@16: // type_traits::type_abs (self_type::imag (t))); Chris@16: } Chris@16: Chris@16: static Chris@16: BOOST_UBLAS_INLINE Chris@16: bool equals (const_reference t1, const_reference t2) { Chris@16: return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON * Chris@16: (std::max) ((std::max) (self_type::norm_inf (t1), Chris@16: self_type::norm_inf (t2)), Chris@16: BOOST_UBLAS_TYPE_CHECK_MIN); Chris@16: } Chris@16: }; Chris@16: Chris@16: // Define complex type traits Chris@16: template<> Chris@16: struct type_traits > : complex_traits >{ Chris@16: typedef type_traits > self_type; Chris@16: typedef std::complex value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef float real_type; Chris@16: typedef std::complex precision_type; Chris@16: Chris@16: }; Chris@16: template<> Chris@16: struct type_traits > : complex_traits >{ Chris@16: typedef type_traits > self_type; Chris@16: typedef std::complex value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef double real_type; Chris@16: typedef std::complex precision_type; Chris@16: }; Chris@16: template<> Chris@16: struct type_traits > : complex_traits > { Chris@16: typedef type_traits > self_type; Chris@16: typedef std::complex value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef long double real_type; Chris@16: typedef value_type precision_type; Chris@16: }; Chris@16: Chris@16: #ifdef BOOST_UBLAS_USE_INTERVAL Chris@16: // Define scalar interval type traits Chris@16: template<> Chris@16: struct type_traits > : scalar_traits > { Chris@16: typedef type_traits > self_type; Chris@16: typedef boost::numeric::interval value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef value_type real_type; Chris@16: typedef boost::numeric::interval precision_type; Chris@16: Chris@16: }; Chris@16: template<> Chris@16: struct type_traits > : scalar_traits > { Chris@16: typedef type_traits > self_type; Chris@16: typedef boost::numeric::interval value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef value_type real_type; Chris@16: typedef boost::numeric::interval precision_type; Chris@16: }; Chris@16: template<> Chris@16: struct type_traits > : scalar_traits > { Chris@16: typedef type_traits > self_type; Chris@16: typedef boost::numeric::interval value_type; Chris@16: typedef const value_type &const_reference; Chris@16: typedef value_type &reference; Chris@16: typedef value_type real_type; Chris@16: typedef value_type precision_type; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: Chris@16: // Storage tags -- hierarchical definition of storage characteristics Chris@16: Chris@16: struct unknown_storage_tag {}; Chris@16: struct sparse_proxy_tag: public unknown_storage_tag {}; Chris@16: struct sparse_tag: public sparse_proxy_tag {}; Chris@16: struct packed_proxy_tag: public sparse_proxy_tag {}; Chris@16: struct packed_tag: public packed_proxy_tag {}; Chris@16: struct dense_proxy_tag: public packed_proxy_tag {}; Chris@16: struct dense_tag: public dense_proxy_tag {}; Chris@16: Chris@16: template Chris@16: struct storage_restrict_traits { Chris@16: typedef S1 storage_category; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef sparse_proxy_tag storage_category; Chris@16: }; Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef sparse_proxy_tag storage_category; Chris@16: }; Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef sparse_proxy_tag storage_category; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef packed_proxy_tag storage_category; Chris@16: }; Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef packed_proxy_tag storage_category; Chris@16: }; Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef sparse_proxy_tag storage_category; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef sparse_proxy_tag storage_category; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef dense_proxy_tag storage_category; Chris@16: }; Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef packed_proxy_tag storage_category; Chris@16: }; Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef sparse_proxy_tag storage_category; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef packed_proxy_tag storage_category; Chris@16: }; Chris@16: template<> Chris@16: struct storage_restrict_traits { Chris@16: typedef sparse_proxy_tag storage_category; Chris@16: }; Chris@16: Chris@16: Chris@16: // Iterator tags -- hierarchical definition of storage characteristics Chris@16: Chris@16: struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {}; Chris@16: struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {}; Chris@16: struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {}; Chris@16: Chris@16: // Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-) Chris@16: template Chris@16: struct iterator_base_traits {}; Chris@16: Chris@16: template<> Chris@16: struct iterator_base_traits { Chris@16: template Chris@16: struct iterator_base { Chris@16: typedef forward_iterator_base type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct iterator_base_traits { Chris@16: template Chris@16: struct iterator_base { Chris@16: typedef bidirectional_iterator_base type; Chris@16: }; Chris@16: }; Chris@16: template<> Chris@16: struct iterator_base_traits { Chris@16: template Chris@16: struct iterator_base { Chris@16: typedef bidirectional_iterator_base type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct iterator_base_traits { Chris@16: template Chris@16: struct iterator_base { Chris@16: typedef random_access_iterator_base type; Chris@16: }; Chris@16: }; Chris@16: template<> Chris@16: struct iterator_base_traits { Chris@16: template Chris@16: struct iterator_base { Chris@16: typedef random_access_iterator_base type; Chris@16: }; Chris@16: }; Chris@16: template<> Chris@16: struct iterator_base_traits { Chris@16: template Chris@16: struct iterator_base { Chris@16: typedef random_access_iterator_base type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct iterator_restrict_traits { Chris@16: typedef I1 iterator_category; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct iterator_restrict_traits { Chris@16: typedef sparse_bidirectional_iterator_tag iterator_category; Chris@16: }; Chris@16: template<> Chris@16: struct iterator_restrict_traits { Chris@16: typedef sparse_bidirectional_iterator_tag iterator_category; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct iterator_restrict_traits { Chris@16: typedef sparse_bidirectional_iterator_tag iterator_category; Chris@16: }; Chris@16: template<> Chris@16: struct iterator_restrict_traits { Chris@16: typedef sparse_bidirectional_iterator_tag iterator_category; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct iterator_restrict_traits { Chris@16: typedef packed_random_access_iterator_tag iterator_category; Chris@16: }; Chris@16: template<> Chris@16: struct iterator_restrict_traits { Chris@16: typedef packed_random_access_iterator_tag iterator_category; Chris@16: }; Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) { Chris@16: it += (std::min) (compare, it_end - it); Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (I &it, const I &/* it_end */, typename I::difference_type /* compare */, sparse_bidirectional_iterator_tag) { Chris@16: ++ it; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (I &it, const I &it_end, typename I::difference_type compare) { Chris@16: increment (it, it_end, compare, typename I::iterator_category ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (I &it, const I &it_end) { Chris@16: #if BOOST_UBLAS_TYPE_CHECK Chris@16: I cit (it); Chris@16: while (cit != it_end) { Chris@16: BOOST_UBLAS_CHECK (*cit == typename I::value_type/*zero*/(), internal_logic ()); Chris@16: ++ cit; Chris@16: } Chris@16: #endif Chris@16: it = it_end; Chris@16: } Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: // specialisation which define whether a type has a trivial constructor Chris@16: // or not. This is used by array types. Chris@16: template Chris@16: struct has_trivial_constructor : public boost::has_trivial_constructor {}; Chris@16: Chris@16: template Chris@16: struct has_trivial_destructor : public boost::has_trivial_destructor {}; Chris@16: Chris@16: template Chris@16: struct has_trivial_constructor > : public has_trivial_constructor {}; Chris@16: Chris@16: template Chris@16: struct has_trivial_destructor > : public has_trivial_destructor {}; Chris@16: Chris@16: } Chris@16: Chris@16: Chris@16: /** \brief Traits class to extract type information from a constant matrix or vector CONTAINER. Chris@16: * Chris@16: */ Chris@16: template < class E > Chris@16: struct container_view_traits { Chris@16: /// type of indices Chris@16: typedef typename E::size_type size_type; Chris@16: /// type of differences of indices Chris@16: typedef typename E::difference_type difference_type; Chris@16: Chris@16: /// storage category: \c unknown_storage_tag, \c dense_tag, \c packed_tag, ... Chris@16: typedef typename E::storage_category storage_category; Chris@16: Chris@16: /// type of elements Chris@16: typedef typename E::value_type value_type; Chris@16: /// const reference to an element Chris@16: typedef typename E::const_reference const_reference; Chris@16: Chris@16: /// type used in expressions to mark a reference to this class (usually a const container_reference or the class itself) Chris@16: typedef typename E::const_closure_type const_closure_type; Chris@16: }; Chris@16: Chris@16: /** \brief Traits class to extract additional type information from a mutable matrix or vector CONTAINER. Chris@16: * Chris@16: */ Chris@16: template < class E > Chris@16: struct mutable_container_traits { Chris@16: /// reference to an element Chris@16: typedef typename E::reference reference; Chris@16: Chris@16: /// type used in expressions to mark a reference to this class (usually a container_reference or the class itself) Chris@16: typedef typename E::closure_type closure_type; Chris@16: }; Chris@16: Chris@16: /** \brief Traits class to extract type information from a matrix or vector CONTAINER. Chris@16: * Chris@16: */ Chris@16: template < class E > Chris@16: struct container_traits Chris@16: : container_view_traits, mutable_container_traits { Chris@16: Chris@16: }; Chris@16: Chris@16: Chris@16: /** \brief Traits class to extract type information from a constant MATRIX. Chris@16: * Chris@16: */ Chris@16: template < class MATRIX > Chris@16: struct matrix_view_traits : container_view_traits { Chris@16: Chris@16: /// orientation of the matrix, either \c row_major_tag, \c column_major_tag or \c unknown_orientation_tag Chris@16: typedef typename MATRIX::orientation_category orientation_category; Chris@16: Chris@16: /// row iterator for the matrix Chris@16: typedef typename MATRIX::const_iterator1 const_iterator1; Chris@16: Chris@16: /// column iterator for the matrix Chris@16: typedef typename MATRIX::const_iterator2 const_iterator2; Chris@16: }; Chris@16: Chris@16: /** \brief Traits class to extract additional type information from a mutable MATRIX. Chris@16: * Chris@16: */ Chris@16: template < class MATRIX > Chris@16: struct mutable_matrix_traits Chris@16: : mutable_container_traits { Chris@16: Chris@16: /// row iterator for the matrix Chris@16: typedef typename MATRIX::iterator1 iterator1; Chris@16: Chris@16: /// column iterator for the matrix Chris@16: typedef typename MATRIX::iterator2 iterator2; Chris@16: }; Chris@16: Chris@16: Chris@16: /** \brief Traits class to extract type information from a MATRIX. Chris@16: * Chris@16: */ Chris@16: template < class MATRIX > Chris@16: struct matrix_traits Chris@16: : matrix_view_traits , mutable_matrix_traits { Chris@16: }; Chris@16: Chris@16: /** \brief Traits class to extract type information from a VECTOR. Chris@16: * Chris@16: */ Chris@16: template < class VECTOR > Chris@16: struct vector_view_traits : container_view_traits { Chris@16: Chris@16: /// iterator for the VECTOR Chris@16: typedef typename VECTOR::const_iterator const_iterator; Chris@16: Chris@16: /// iterator pointing to the first element Chris@16: static Chris@16: const_iterator begin(const VECTOR & v) { Chris@16: return v.begin(); Chris@16: } Chris@16: /// iterator pointing behind the last element Chris@16: static Chris@16: const_iterator end(const VECTOR & v) { Chris@16: return v.end(); Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: /** \brief Traits class to extract type information from a VECTOR. Chris@16: * Chris@16: */ Chris@16: template < class VECTOR > Chris@16: struct mutable_vector_traits : mutable_container_traits { Chris@16: /// iterator for the VECTOR Chris@16: typedef typename VECTOR::iterator iterator; Chris@16: Chris@16: /// iterator pointing to the first element Chris@16: static Chris@16: iterator begin(VECTOR & v) { Chris@16: return v.begin(); Chris@16: } Chris@16: Chris@16: /// iterator pointing behind the last element Chris@16: static Chris@16: iterator end(VECTOR & v) { Chris@16: return v.end(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /** \brief Traits class to extract type information from a VECTOR. Chris@16: * Chris@16: */ Chris@16: template < class VECTOR > Chris@16: struct vector_traits Chris@16: : vector_view_traits , mutable_vector_traits { Chris@16: }; Chris@16: Chris@16: Chris@16: // Note: specializations for T[N] and T[M][N] have been moved to traits/c_array.hpp Chris@16: Chris@16: }}} Chris@16: Chris@16: #endif