diff --git a/include/boost/numeric/ublas/matrix_expression.hpp b/include/boost/numeric/ublas/matrix_expression.hpp index fb038574..e7bf9109 100644 --- a/include/boost/numeric/ublas/matrix_expression.hpp +++ b/include/boost/numeric/ublas/matrix_expression.hpp @@ -37,19 +37,9 @@ namespace boost { namespace numeric { namespace ublas { typedef E expression_type; typedef matrix_tag type_category; typedef abstract_tag simd_category; - // FIXME Template instantiation order problem - // typedef typename E::size_type size_type; - typedef std::size_t size_type; - typedef const matrix_row const_matrix_row_type; - typedef matrix_row matrix_row_type; - typedef const matrix_column const_matrix_column_type; - typedef matrix_column matrix_column_type; - typedef const matrix_range const_matrix_range_type; - typedef matrix_range matrix_range_type; - typedef const matrix_slice const_matrix_slice_type; - typedef matrix_slice matrix_slice_type; - typedef const matrix_indirect const_matrix_indirect_type; - typedef matrix_indirect matrix_indirect_type; + /* E can be an incomplete type - to define the following we would need more template arguments + typedef typename E::size_type size_type; + */ BOOST_UBLAS_INLINE const expression_type &operator () () const { @@ -60,83 +50,113 @@ namespace boost { namespace numeric { namespace ublas { return *static_cast (this); } + private: + // projection types + typedef vector_range vector_range_type; + typedef vector_slice vector_slice_type; + typedef matrix_row matrix_row_type; + typedef matrix_column matrix_column_type; + typedef matrix_range matrix_range_type; + typedef matrix_slice matrix_slice_type; + // matrix_indirect_type will depend on the A template parameter + typedef basic_range<> default_range; + typedef basic_slice<> default_slice; + + public: + // projection functions - projects must be constructable from default size_t, range and slice types BOOST_UBLAS_INLINE - const_matrix_row_type operator [] (size_type i) const { - return const_matrix_row_type (operator () (), i); - } - BOOST_UBLAS_INLINE - matrix_row_type operator [] (size_type i) { + const matrix_row_type operator [] (std::size_t i) const { return matrix_row_type (operator () (), i); } BOOST_UBLAS_INLINE - const_matrix_row_type row (size_type i) const { - return const_matrix_row_type (operator () (), i); - } - BOOST_UBLAS_INLINE - matrix_row_type row (size_type i) { + matrix_row_type operator [] (std::size_t i) { return matrix_row_type (operator () (), i); } BOOST_UBLAS_INLINE - const_matrix_column_type column (size_type j) const { - return const_matrix_column_type (operator () (), j); + const matrix_row_type row (std::size_t i) const { + return matrix_row_type (operator () (), i); } BOOST_UBLAS_INLINE - matrix_column_type column (size_type j) { + matrix_row_type row (std::size_t i) { + return matrix_row_type (operator () (), i); + } + BOOST_UBLAS_INLINE + const matrix_column_type column (std::size_t j) const { return matrix_column_type (operator () (), j); } + BOOST_UBLAS_INLINE + matrix_column_type column (std::size_t j) { + return matrix_column_type (operator () (), j); + } + BOOST_UBLAS_INLINE + const matrix_range_type range (std::size_t start1, std::size_t stop1, std::size_t start2, std::size_t stop2) const { + return matrix_range_type (operator () (), default_range (start1, stop1), default_range (start2, stop2)); + } + BOOST_UBLAS_INLINE + matrix_range_type range (std::size_t start1, std::size_t stop1, std::size_t start2, std::size_t stop2) { + return matrix_range_type (operator () (), default_range (start1, stop1), default_range (start2, stop2)); + } + BOOST_UBLAS_INLINE + const matrix_slice_type slice (std::size_t start1, std::ptrdiff_t stride1, std::size_t size1, std::size_t start2, std::ptrdiff_t stride2, std::size_t size2) const { + return matrix_slice_type (operator () (), default_slice (start1, stride1, size1), default_slice (start2, stride2, size2)); + } + BOOST_UBLAS_INLINE + matrix_slice_type slice (std::size_t start1, std::ptrdiff_t stride1, std::size_t size1, std::size_t start2, std::ptrdiff_t stride2, std::size_t size2) { + return matrix_slice_type (operator () (), default_slice (start1, stride1, size1), default_slice (start2, stride2, size2)); + } #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS BOOST_UBLAS_INLINE - const_matrix_range_type operator () (const range &r1, const range &r2) const { - return const_matrix_range_type (operator () (), r1, r2); - } - BOOST_UBLAS_INLINE - matrix_range_type operator () (const range &r1, const range &r2) { + const matrix_range_type operator () (const default_range &r1, const default_range &r2) const { return matrix_range_type (operator () (), r1, r2); } BOOST_UBLAS_INLINE - const_matrix_slice_type operator () (const slice &s1, const slice &s2) const { - return const_matrix_slice_type (operator () (), s1, s2); + matrix_range_type operator () (const default_range &r1, const default_range &r2) { + return matrix_range_type (operator () (), r1, r2); } BOOST_UBLAS_INLINE - matrix_slice_type operator () (const slice &s1, const slice &s2) { + const matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) const { + return matrix_slice_type (operator () (), s1, s2); + } + BOOST_UBLAS_INLINE + matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) { return matrix_slice_type (operator () (), s1, s2); } template BOOST_UBLAS_INLINE - const_matrix_indirect_type operator () (const indirect_array &ia1, const indirect_array &ia2) const { - return const_matrix_indirect_type (operator () (), ia1, ia2); + const matrix_indirect operator () (const indirect_array &ia1, const indirect_array &ia2) const { + return matrix_indirect (operator () (), ia1, ia2); } template BOOST_UBLAS_INLINE - matrix_indirect_type operator () (const indirect_array &ia1, const indirect_array &ia2) { - return matrix_indirect_type (operator () (), ia1, ia2); + matrix_indirect operator () (const indirect_array &ia1, const indirect_array &ia2) { + return matrix_indirect (operator () (), ia1, ia2); } #endif BOOST_UBLAS_INLINE - const_matrix_range_type project (const range &r1, const range &r2) const { - return const_matrix_range_type (operator () (), r1, r2); - } - BOOST_UBLAS_INLINE - matrix_range_type project (const range &r1, const range &r2) { + const matrix_range_type project (const default_range &r1, const default_range &r2) const { return matrix_range_type (operator () (), r1, r2); } BOOST_UBLAS_INLINE - const_matrix_slice_type project (const slice &s1, const slice &s2) const { - return const_matrix_slice_type (operator () (), s1, s2); + matrix_range_type project (const default_range &r1, const default_range &r2) { + return matrix_range_type (operator () (), r1, r2); } BOOST_UBLAS_INLINE - matrix_slice_type project (const slice &s1, const slice &s2) { + const matrix_slice_type project (const default_slice &s1, const default_slice &s2) const { + return matrix_slice_type (operator () (), s1, s2); + } + BOOST_UBLAS_INLINE + matrix_slice_type project (const default_slice &s1, const default_slice &s2) { return matrix_slice_type (operator () (), s1, s2); } template BOOST_UBLAS_INLINE - const_matrix_indirect_type project (const indirect_array &ia1, const indirect_array &ia2) const { - return const_matrix_indirect_type (operator () (), ia1, ia2); + const matrix_indirect project (const indirect_array &ia1, const indirect_array &ia2) const { + return matrix_indirect (operator () (), ia1, ia2); } template BOOST_UBLAS_INLINE - matrix_indirect_type project (const indirect_array &ia1, const indirect_array &ia2) { - return matrix_indirect_type (operator () (), ia1, ia2); + matrix_indirect project (const indirect_array &ia1, const indirect_array &ia2) { + return matrix_indirect (operator () (), ia1, ia2); } }; diff --git a/include/boost/numeric/ublas/vector_expression.hpp b/include/boost/numeric/ublas/vector_expression.hpp index 1d6d1aae..2549b89b 100644 --- a/include/boost/numeric/ublas/vector_expression.hpp +++ b/include/boost/numeric/ublas/vector_expression.hpp @@ -29,14 +29,11 @@ namespace boost { namespace numeric { namespace ublas { // Base class for uBLAS staticaly derived expressions - see the Barton Nackman trick // Provides numeric properties for linear algebra - // FIXME - // The template instantiation order needs to be analyses to ensure - // class typedefs of E are fully defined. template class ublas_expression { public: typedef E expression_type; - /* FIXME + /* E can be an incomplete type - to define the following we would need more template arguments typedef typename E::type_category type_category; typedef typename E::value_type value_type; */ @@ -187,16 +184,10 @@ namespace boost { namespace numeric { namespace ublas { typedef E expression_type; typedef vector_tag type_category; typedef abstract_tag simd_category; - // FIXME Template instantiation order problem - // typedef typename E::size_type size_type; + /* E can be an incomplete type - to define the following we would need more template arguments + typedef typename E::size_type size_type; + */ - typedef const vector_range const_vector_range_type; - typedef vector_range vector_range_type; - typedef const vector_slice const_vector_slice_type; - typedef vector_slice vector_slice_type; - typedef const vector_indirect const_vector_indirect_type; - typedef vector_indirect vector_indirect_type; - BOOST_UBLAS_INLINE const expression_type &operator () () const { return *static_cast (this); @@ -206,62 +197,83 @@ namespace boost { namespace numeric { namespace ublas { return *static_cast (this); } + private: + // projection types + typedef vector_range vector_range_type; + typedef vector_slice vector_slice_type; + // vector_indirect_type will depend on the A template parameter + typedef basic_range<> default_range; + typedef basic_slice<> default_slice; + public: + // projection functions - projects must be constructable from default size_t, range and slice types + BOOST_UBLAS_INLINE + const vector_range_type range (std::size_t start, std::size_t stop) const { + return vector_range_type (operator () (), default_range (start, stop)); + } + vector_range_type range (std::size_t start, std::size_t stop) { + return vector_range_type (operator () (), default_range (start, stop)); + } #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS BOOST_UBLAS_INLINE - const_vector_range_type operator () (const range &r) const { - return const_vector_range_type (operator () (), r); - } - BOOST_UBLAS_INLINE - vector_range_type operator () (const range &r) { + const vector_range_type operator () (const default_range &r) const { return vector_range_type (operator () (), r); } BOOST_UBLAS_INLINE - const_vector_slice_type operator () (const slice &s) const { - return const_vector_slice_type (operator () (), s); + vector_range_type operator () (const default_range &r) { + return vector_range_type (operator () (), r); } BOOST_UBLAS_INLINE - vector_slice_type operator () (const slice &s) { + const vector_slice_type operator () (const default_slice &s) const { + return vector_slice_type (operator () (), s); + } + BOOST_UBLAS_INLINE + vector_slice_type operator () (const default_slice &s) { return vector_slice_type (operator () (), s); } template BOOST_UBLAS_INLINE - const_vector_indirect_type operator () (const indirect_array &ia) const { - return const_vector_indirect_type (operator () (), ia); + const vector_indirect operator () (const indirect_array &ia) const { + return vector_indirect (operator () (), ia); } template BOOST_UBLAS_INLINE - vector_indirect_type operator () (const indirect_array &ia) { - return vector_indirect_type (operator () (), ia); + vector_indirect operator () (const indirect_array &ia) { + return vector_indirect (operator () (), ia); } #endif BOOST_UBLAS_INLINE - const_vector_range_type project (const range &r) const { - return const_vector_range_type (operator () (), r); - } - BOOST_UBLAS_INLINE - vector_range_type project (const range &r) { + const vector_range_type project (const default_range &r) const { return vector_range_type (operator () (), r); } BOOST_UBLAS_INLINE - const_vector_slice_type project (const slice &s) const { - return const_vector_slice_type (operator () (), s); + vector_range_type project (const default_range &r) { + return vector_range_type (operator () (), r); } BOOST_UBLAS_INLINE - vector_slice_type project (const slice &s) { + const vector_slice_type project (const default_slice &s) const { + return vector_slice_type (operator () (), s); + } + BOOST_UBLAS_INLINE + vector_slice_type project (const default_slice &s) { return vector_slice_type (operator () (), s); } template BOOST_UBLAS_INLINE - const_vector_indirect_type project (const indirect_array &ia) const { - return const_vector_indirect_type (operator () (), ia); + const vector_indirect project (const indirect_array &ia) const { + return vector_indirect (operator () (), ia); } template BOOST_UBLAS_INLINE - vector_indirect_type project (const indirect_array &ia) { - return vector_indirect_type (operator () (), ia); + vector_indirect project (const indirect_array &ia) { + return vector_indirect (operator () (), ia); } }; + + /* + * All subsequent classes model the Vector Expression concept + */ + template class vector_reference: public vector_expression > {