From e97ac86cefc44ae5074fc4aa4c7d8ef2fb0f3f12 Mon Sep 17 00:00:00 2001 From: Michael Stevens Date: Thu, 30 Sep 2004 21:09:17 +0000 Subject: [PATCH] Change use functor_type::apply syntax replaces functor () () which again overloads () and may have overhead on some compilers Add correct infrastructure for scalar_expressions svn path=/trunk/boost/boost/numeric/ublas/; revision=25492 --- include/boost/numeric/ublas/concepts.hpp | 58 ++- include/boost/numeric/ublas/functional.hpp | 322 ++++++++------- include/boost/numeric/ublas/matrix_assign.hpp | 92 ++--- .../boost/numeric/ublas/matrix_expression.hpp | 279 ++++++------- include/boost/numeric/ublas/vector_assign.hpp | 38 +- .../boost/numeric/ublas/vector_expression.hpp | 372 +++++++++++------- 6 files changed, 632 insertions(+), 529 deletions(-) diff --git a/include/boost/numeric/ublas/concepts.hpp b/include/boost/numeric/ublas/concepts.hpp index 1f2dc928..14ba2e59 100644 --- a/include/boost/numeric/ublas/concepts.hpp +++ b/include/boost/numeric/ublas/concepts.hpp @@ -932,7 +932,7 @@ namespace boost { namespace numeric { namespace ublas { typedef BOOST_UBLAS_TYPENAME promote_traits::promote_type value_type; typedef BOOST_UBLAS_TYPENAME type_traits::real_type real_type; - return norm_inf (e1 - e2) == real_type (); + return norm_inf (e1 - e2) == real_type (0); } template bool @@ -940,7 +940,7 @@ namespace boost { namespace numeric { namespace ublas { typedef BOOST_UBLAS_TYPENAME promote_traits::promote_type value_type; typedef BOOST_UBLAS_TYPENAME type_traits::real_type real_type; - return norm_inf (e1 - e2) == real_type (); + return norm_inf (e1 - e2) == real_type (0); } template @@ -1485,7 +1485,7 @@ namespace boost { namespace numeric { namespace ublas { // Scalar Expressions #if defined (INTERNAL) || defined (INTERNAL_VECTOR_EXPRESSION) ScalarExpressionConcept >::constraints (); - ScalarExpressionConcept >::constraints (); + ScalarExpressionConcept >::constraints (); // Vector Expressions #ifndef BOOST_UBLAS_CT_REFERENCE_BASE_TYPEDEFS @@ -1509,13 +1509,21 @@ namespace boost { namespace numeric { namespace ublas { IndexedRandomAccess1DIteratorConcept, vector, scalar_plus >::const_iterator>::constraints (); IndexedRandomAccess1DIteratorConcept, vector, scalar_plus >::const_reverse_iterator>::constraints (); - VectorExpressionConcept, vector, scalar_multiplies > >::constraints (); - IndexedRandomAccess1DIteratorConcept, vector, scalar_multiplies >::const_iterator>::constraints (); - IndexedRandomAccess1DIteratorConcept, vector, scalar_multiplies >::const_reverse_iterator>::constraints (); + VectorExpressionConcept, scalar_multiplies, scalar_reference > >::constraints (); + IndexedRandomAccess1DIteratorConcept, scalar_multiplies, scalar_reference >::const_iterator>::constraints (); + IndexedRandomAccess1DIteratorConcept, scalar_multiplies, scalar_reference >::const_reverse_iterator>::constraints (); - VectorExpressionConcept, scalar_value, scalar_multiplies > >::constraints (); - IndexedRandomAccess1DIteratorConcept, scalar_value, scalar_multiplies >::const_iterator>::constraints (); - IndexedRandomAccess1DIteratorConcept, scalar_value, scalar_multiplies >::const_reverse_iterator>::constraints (); + VectorExpressionConcept, scalar_value, scalar_multiplies, scalar_reference > >::constraints (); + IndexedRandomAccess1DIteratorConcept, scalar_value, scalar_multiplies, scalar_reference >::const_iterator>::constraints (); + IndexedRandomAccess1DIteratorConcept, scalar_value, scalar_multiplies, scalar_reference >::const_reverse_iterator>::constraints (); + + VectorExpressionConcept, vector, scalar_multiplies, scalar_reference > > >::constraints (); + IndexedRandomAccess1DIteratorConcept, vector, scalar_multiplies, scalar_reference > >::const_iterator>::constraints (); + IndexedRandomAccess1DIteratorConcept, vector, scalar_multiplies, scalar_reference > >::const_reverse_iterator>::constraints (); + + VectorExpressionConcept, scalar_value, scalar_multiplies, scalar_reference > > >::constraints (); + IndexedRandomAccess1DIteratorConcept, scalar_value, scalar_multiplies, scalar_reference > >::const_iterator>::constraints (); + IndexedRandomAccess1DIteratorConcept, scalar_value, scalar_multiplies, scalar_reference > >::const_reverse_iterator>::constraints (); ScalarExpressionConcept, vector_sum > >::constraints (); ScalarExpressionConcept, vector_norm_1 > >::constraints (); @@ -1562,17 +1570,29 @@ namespace boost { namespace numeric { namespace ublas { IndexedRandomAccess2DIteratorConcept, matrix, scalar_plus >::const_reverse_iterator1, matrix_binary, matrix, scalar_plus >::const_reverse_iterator2>::constraints (); - MatrixExpressionConcept, matrix, scalar_multiplies > >::constraints (); - IndexedRandomAccess2DIteratorConcept, matrix, scalar_multiplies >::const_iterator1, - matrix_binary_scalar1, matrix, scalar_multiplies >::const_iterator2>::constraints (); - IndexedRandomAccess2DIteratorConcept, matrix, scalar_multiplies >::const_reverse_iterator1, - matrix_binary_scalar1, matrix, scalar_multiplies >::const_reverse_iterator2>::constraints (); + MatrixExpressionConcept, scalar_multiplies, scalar_reference > >::constraints (); + IndexedRandomAccess2DIteratorConcept, scalar_multiplies, scalar_reference >::const_iterator1, + matrix_binary_scalar1, scalar_multiplies, scalar_reference >::const_iterator2>::constraints (); + IndexedRandomAccess2DIteratorConcept, scalar_multiplies, scalar_reference >::const_reverse_iterator1, + matrix_binary_scalar1, scalar_multiplies, scalar_reference >::const_reverse_iterator2>::constraints (); - MatrixExpressionConcept, scalar_value, scalar_multiplies > >::constraints (); - IndexedRandomAccess2DIteratorConcept, scalar_value, scalar_multiplies >::const_iterator1, - matrix_binary_scalar2, scalar_value, scalar_multiplies >::const_iterator2>::constraints (); - IndexedRandomAccess2DIteratorConcept, scalar_value, scalar_multiplies >::const_reverse_iterator1, - matrix_binary_scalar2, scalar_value, scalar_multiplies >::const_reverse_iterator2>::constraints (); + MatrixExpressionConcept, double, scalar_multiplies, scalar_reference > >::constraints (); + IndexedRandomAccess2DIteratorConcept, double, scalar_multiplies, scalar_reference >::const_iterator1, + matrix_binary_scalar2, double, scalar_multiplies, scalar_reference >::const_iterator2>::constraints (); + IndexedRandomAccess2DIteratorConcept, double, scalar_multiplies, scalar_reference >::const_reverse_iterator1, + matrix_binary_scalar2, double, scalar_multiplies, scalar_reference >::const_reverse_iterator2>::constraints (); + + MatrixExpressionConcept, matrix, scalar_multiplies, scalar_reference > > >::constraints (); + IndexedRandomAccess2DIteratorConcept, matrix, scalar_multiplies, scalar_reference > >::const_iterator1, + matrix_binary_scalar1, matrix, scalar_multiplies, scalar_reference > >::const_iterator2>::constraints (); + IndexedRandomAccess2DIteratorConcept, matrix, scalar_multiplies, scalar_reference > >::const_reverse_iterator1, + matrix_binary_scalar1, matrix, scalar_multiplies, scalar_reference > >::const_reverse_iterator2>::constraints (); + + MatrixExpressionConcept, scalar_value, scalar_multiplies, scalar_reference > > >::constraints (); + IndexedRandomAccess2DIteratorConcept, scalar_value, scalar_multiplies, scalar_reference > >::const_iterator1, + matrix_binary_scalar2, scalar_value, scalar_multiplies, scalar_reference > >::const_iterator2>::constraints (); + IndexedRandomAccess2DIteratorConcept, scalar_value, scalar_multiplies, scalar_reference > >::const_reverse_iterator1, + matrix_binary_scalar2, scalar_value, scalar_multiplies, scalar_reference > >::const_reverse_iterator2>::constraints (); VectorExpressionConcept, vector, matrix_vector_prod1 > >::constraints (); IndexedRandomAccess1DIteratorConcept, vector, matrix_vector_prod1 >::const_iterator>::constraints (); diff --git a/include/boost/numeric/ublas/functional.hpp b/include/boost/numeric/ublas/functional.hpp index 081cba0e..e94a94b9 100644 --- a/include/boost/numeric/ublas/functional.hpp +++ b/include/boost/numeric/ublas/functional.hpp @@ -58,8 +58,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_unary_functor::argument_type argument_type; typedef typename scalar_unary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument_type t) const { + static BOOST_UBLAS_INLINE + result_type apply (argument_type t) { return t; } }; @@ -69,8 +69,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_unary_functor::argument_type argument_type; typedef typename scalar_unary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument_type t) const { + static BOOST_UBLAS_INLINE + result_type apply (argument_type t) { return - t; } }; @@ -81,8 +81,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_unary_functor::argument_type argument_type; typedef typename scalar_unary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument_type t) const { + static BOOST_UBLAS_INLINE + result_type apply (argument_type t) { return type_traits::conj (t); } }; @@ -102,8 +102,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_real_unary_functor::argument_type argument_type; typedef typename scalar_real_unary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument_type t) const { + static BOOST_UBLAS_INLINE + result_type apply (argument_type t) { return type_traits::real (t); } }; @@ -114,8 +114,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_real_unary_functor::argument_type argument_type; typedef typename scalar_real_unary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument_type t) const { + static BOOST_UBLAS_INLINE + result_type apply (argument_type t) { return type_traits::imag (t); } }; @@ -135,8 +135,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_functor::argument2_type argument2_type; typedef typename scalar_binary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + result_type apply (argument1_type t1, argument2_type t2) { return t1 + t2; } }; @@ -147,8 +147,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_functor::argument2_type argument2_type; typedef typename scalar_binary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + result_type apply (argument1_type t1, argument2_type t2) { return t1 - t2; } }; @@ -159,8 +159,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_functor::argument2_type argument2_type; typedef typename scalar_binary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + result_type apply (argument1_type t1, argument2_type t2) { return t1 * t2; } }; @@ -171,8 +171,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_functor::argument2_type argument2_type; typedef typename scalar_binary_functor::result_type result_type; - BOOST_UBLAS_INLINE - result_type operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + result_type apply (argument1_type t1, argument2_type t2) { return t1 / t2; } }; @@ -194,14 +194,13 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_assign_functor::argument2_type argument2_type; typedef assign_tag assign_category; - BOOST_UBLAS_INLINE - void operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + void apply (argument1_type t1, argument2_type t2) { t1 = t2; } template - static - BOOST_UBLAS_INLINE + static BOOST_UBLAS_INLINE scalar_assign make_debug_functor () { return scalar_assign (); } @@ -214,14 +213,13 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_assign_functor::argument2_type argument2_type; typedef computed_assign_tag assign_category; - BOOST_UBLAS_INLINE - void operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + void apply (argument1_type t1, argument2_type t2) { t1 += t2; } template - static - BOOST_UBLAS_INLINE + static BOOST_UBLAS_INLINE scalar_plus_assign make_debug_functor () { return scalar_plus_assign (); } @@ -233,14 +231,13 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_assign_functor::argument2_type argument2_type; typedef computed_assign_tag assign_category; - BOOST_UBLAS_INLINE - void operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + void apply (argument1_type t1, argument2_type t2) { t1 -= t2; } template - static - BOOST_UBLAS_INLINE + static BOOST_UBLAS_INLINE scalar_minus_assign make_debug_functor () { return scalar_minus_assign (); } @@ -252,14 +249,13 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_assign_functor::argument2_type argument2_type; typedef computed_assign_tag assign_category; - BOOST_UBLAS_INLINE - void operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + void apply (argument1_type t1, argument2_type t2) { t1 *= t2; } template - static - BOOST_UBLAS_INLINE + static BOOST_UBLAS_INLINE scalar_multiplies_assign make_debug_functor () { return scalar_multiplies_assign (); } @@ -271,14 +267,13 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_assign_functor::argument2_type argument2_type; typedef computed_assign_tag assign_category; - BOOST_UBLAS_INLINE - void operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + void apply (argument1_type t1, argument2_type t2) { t1 /= t2; } template - static - BOOST_UBLAS_INLINE + static BOOST_UBLAS_INLINE scalar_divides_assign make_debug_functor () { return scalar_divides_assign (); } @@ -296,14 +291,13 @@ namespace boost { namespace numeric { namespace ublas { typedef typename scalar_binary_swap_functor::argument1_type argument1_type; typedef typename scalar_binary_swap_functor::argument2_type argument2_type; - BOOST_UBLAS_INLINE - void operator () (argument1_type t1, argument2_type t2) const { + static BOOST_UBLAS_INLINE + void apply (argument1_type t1, argument2_type t2) { std::swap (t1, t2); } template - static - BOOST_UBLAS_INLINE + static BOOST_UBLAS_INLINE scalar_swap make_debug_functor () { return scalar_swap (); } @@ -329,8 +323,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename vector_scalar_unary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e) const { + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e) { result_type t = result_type (0); size_type size (e ().size ()); for (size_type i = 0; i < size; ++ i) @@ -339,8 +333,8 @@ namespace boost { namespace numeric { namespace ublas { } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I it) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I it) { result_type t = result_type (0); while (-- size >= 0) t += *it, ++ it; @@ -348,8 +342,8 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I it, const I &it_end) const { + static BOOST_UBLAS_INLINE + result_type apply (I it, const I &it_end) { result_type t = result_type (0); while (it != it_end) t += *it, ++ it; @@ -377,8 +371,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename vector_scalar_real_unary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e) const { + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e) { real_type t = real_type (); size_type size (e ().size ()); for (size_type i = 0; i < size; ++ i) { @@ -389,8 +383,8 @@ namespace boost { namespace numeric { namespace ublas { } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I it) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I it) { real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits::norm_1 (*it)); @@ -401,8 +395,8 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I it, const I &it_end) const { + static BOOST_UBLAS_INLINE + result_type apply (I it, const I &it_end) { real_type t = real_type (); while (it != it_end) { real_type u (type_traits::norm_1 (*it)); @@ -422,8 +416,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename vector_scalar_real_unary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e) const { + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); size_type size (e ().size ()); @@ -452,8 +446,8 @@ namespace boost { namespace numeric { namespace ublas { } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I it) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I it) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); while (-- size >= 0) { @@ -482,8 +476,8 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I it, const I &it_end) const { + static BOOST_UBLAS_INLINE + result_type apply (I it, const I &it_end) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); while (it != it_end) { @@ -521,8 +515,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename vector_scalar_real_unary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e) const { + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e) { real_type t = real_type (); size_type size (e ().size ()); for (size_type i = 0; i < size; ++ i) { @@ -534,8 +528,8 @@ namespace boost { namespace numeric { namespace ublas { } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I it) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I it) { real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits::norm_inf (*it)); @@ -547,8 +541,8 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I it, const I &it_end) const { + static BOOST_UBLAS_INLINE + result_type apply (I it, const I &it_end) { real_type t = real_type (); while (it != it_end) { real_type u (type_traits::norm_inf (*it)); @@ -580,8 +574,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename vector_scalar_index_unary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e) const { + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); @@ -597,8 +591,8 @@ namespace boost { namespace numeric { namespace ublas { } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I it) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I it) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); @@ -614,8 +608,8 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I it, const I &it_end) const { + static BOOST_UBLAS_INLINE + result_type apply (I it, const I &it_end) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); @@ -649,10 +643,10 @@ namespace boost { namespace numeric { namespace ublas { typedef typename vector_scalar_binary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e1, const vector_expression &e2, - concrete_tag) const { + concrete_tag) { #ifndef BOOST_UBLAS_HAVE_BINDINGS using namespace raw; size_type size (BOOST_UBLAS_SAME (e1 ().size (), e2 ().size ())); @@ -680,10 +674,10 @@ namespace boost { namespace numeric { namespace ublas { #endif } template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e1, const vector_expression &e2, - abstract_tag) const { + abstract_tag) { size_type size (BOOST_UBLAS_SAME (e1 ().size (), e2 ().size ())); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE @@ -696,9 +690,9 @@ namespace boost { namespace numeric { namespace ublas { return t; } template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e1, - const vector_expression &e2) const { + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e1, + const vector_expression &e2) { #ifdef BOOST_UBLAS_USE_SIMD typedef typename boost::mpl::if_< boost::mpl::and_, @@ -708,12 +702,12 @@ namespace boost { namespace numeric { namespace ublas { #else typedef abstract_tag simd_category; #endif - return operator () (e1, e2, simd_category ()); + return apply (e1, e2, simd_category ()); } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I1 it1, I2 it2) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) @@ -725,8 +719,8 @@ namespace boost { namespace numeric { namespace ublas { } // Packed case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); difference_type it1_size (it1_end - it1); difference_type it2_size (it2_end - it2); @@ -754,8 +748,8 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index (), it2_index = it2.index (); @@ -807,10 +801,10 @@ namespace boost { namespace numeric { namespace ublas { typedef typename matrix_vector_binary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e1, const vector_expression &e2, - size_type i, concrete_tag) const { + size_type i, concrete_tag) { #ifndef BOOST_UBLAS_HAVE_BINDINGS using namespace raw; size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ()); @@ -838,10 +832,10 @@ namespace boost { namespace numeric { namespace ublas { #endif } template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e1, const vector_expression &e2, - size_type i, abstract_tag) const { + size_type i, abstract_tag) { size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ()); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE @@ -854,10 +848,10 @@ namespace boost { namespace numeric { namespace ublas { return t; } template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e1, const vector_expression &e2, - size_type i) const { + size_type i) { #ifdef BOOST_UBLAS_USE_SIMD typedef typename boost::mpl::if_< boost::mpl::and_, @@ -867,12 +861,12 @@ namespace boost { namespace numeric { namespace ublas { #else typedef abstract_tag simd_category; #endif - return operator () (e1, e2, i, simd_category ()); + return apply (e1, e2, i, simd_category ()); } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I1 it1, I2 it2) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) @@ -884,8 +878,8 @@ namespace boost { namespace numeric { namespace ublas { } // Packed case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); difference_type it1_size (it1_end - it1); difference_type it2_size (it2_end - it2); @@ -913,9 +907,9 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, - sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, + sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index2 (), it2_index = it2.index (); @@ -947,9 +941,9 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse packed case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */, - sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */, + sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) { result_type t = result_type (0); while (it1 != it1_end) { t += *it1 * it2 () (it1.index2 ()); @@ -959,9 +953,9 @@ namespace boost { namespace numeric { namespace ublas { } // Packed sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end, - packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end, + packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); while (it2 != it2_end) { t += it1 () (it1.index1 (), it2.index ()) * *it2; @@ -971,12 +965,12 @@ namespace boost { namespace numeric { namespace ublas { } // Another dispatcher template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, - sparse_bidirectional_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, + sparse_bidirectional_iterator_tag) { typedef typename I1::iterator_category iterator1_category; typedef typename I2::iterator_category iterator2_category; - return operator () (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ()); + return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ()); } }; @@ -989,10 +983,10 @@ namespace boost { namespace numeric { namespace ublas { typedef typename matrix_vector_binary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e1, const matrix_expression &e2, - size_type i, concrete_tag) const { + size_type i, concrete_tag) { #ifndef BOOST_UBLAS_HAVE_BINDINGS using namespace raw; size_type size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ()); @@ -1020,10 +1014,10 @@ namespace boost { namespace numeric { namespace ublas { #endif } template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e1, const matrix_expression &e2, - size_type i, abstract_tag) const { + size_type i, abstract_tag) { size_type size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ()); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE @@ -1036,10 +1030,10 @@ namespace boost { namespace numeric { namespace ublas { return t; } template - BOOST_UBLAS_INLINE - result_type operator () (const vector_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const vector_expression &e1, const matrix_expression &e2, - size_type i) const { + size_type i) { #ifdef BOOST_UBLAS_USE_SIMD typedef typename boost::mpl::if_< boost::mpl::and_, @@ -1049,12 +1043,12 @@ namespace boost { namespace numeric { namespace ublas { #else typedef abstract_tag simd_category; #endif - return operator () (e1, e2, i, simd_category ()); + return apply (e1, e2, i, simd_category ()); } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I1 it1, I2 it2) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) @@ -1066,8 +1060,8 @@ namespace boost { namespace numeric { namespace ublas { } // Packed case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); difference_type it1_size (it1_end - it1); difference_type it2_size (it2_end - it2); @@ -1095,9 +1089,9 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, - sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, + sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index (), it2_index = it2.index1 (); @@ -1129,9 +1123,9 @@ namespace boost { namespace numeric { namespace ublas { } // Packed sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end, - packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end, + packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); while (it2 != it2_end) { t += it1 () (it2.index1 ()) * *it2; @@ -1141,9 +1135,9 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse packed case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */, - sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */, + sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) { result_type t = result_type (0); while (it1 != it1_end) { t += *it1 * it2 () (it1.index (), it2.index2 ()); @@ -1153,12 +1147,12 @@ namespace boost { namespace numeric { namespace ublas { } // Another dispatcher template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, - sparse_bidirectional_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, + sparse_bidirectional_iterator_tag) { typedef typename I1::iterator_category iterator1_category; typedef typename I2::iterator_category iterator2_category; - return operator () (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ()); + return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ()); } }; @@ -1180,10 +1174,10 @@ namespace boost { namespace numeric { namespace ublas { typedef typename matrix_matrix_binary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e1, const matrix_expression &e2, - size_type i, size_type j, concrete_tag) const { + size_type i, size_type j, concrete_tag) { #ifndef BOOST_UBLAS_HAVE_BINDINGS using namespace raw; size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ()); @@ -1211,10 +1205,10 @@ namespace boost { namespace numeric { namespace ublas { #endif } template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e1, const matrix_expression &e2, - size_type i, size_type j, abstract_tag) const { + size_type i, size_type j, abstract_tag) { size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ()); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE @@ -1227,10 +1221,10 @@ namespace boost { namespace numeric { namespace ublas { return t; } template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e1, + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e1, const matrix_expression &e2, - size_type i, size_type j) const { + size_type i, size_type j) { #ifdef BOOST_UBLAS_USE_SIMD typedef typename boost::mpl::if_< boost::mpl::and_, @@ -1240,12 +1234,12 @@ namespace boost { namespace numeric { namespace ublas { #else typedef abstract_tag simd_category; #endif - return operator () (e1, e2, i, j, simd_category ()); + return apply (e1, e2, i, j, simd_category ()); } // Dense case template - BOOST_UBLAS_INLINE - result_type operator () (difference_type size, I1 it1, I2 it2) const { + static BOOST_UBLAS_INLINE + result_type apply (difference_type size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) @@ -1257,8 +1251,8 @@ namespace boost { namespace numeric { namespace ublas { } // Packed case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, packed_random_access_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, packed_random_access_iterator_tag) { result_type t = result_type (0); difference_type it1_size (it1_end - it1); difference_type it2_size (it2_end - it2); @@ -1286,8 +1280,8 @@ namespace boost { namespace numeric { namespace ublas { } // Sparse case template - BOOST_UBLAS_INLINE - result_type operator () (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) const { + static BOOST_UBLAS_INLINE + result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index2 (), it2_index = it2.index1 (); @@ -1339,8 +1333,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename matrix_scalar_real_unary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e) const { + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e) { real_type t = real_type (); size_type size2 (e ().size2 ()); for (size_type j = 0; j < size2; ++ j) { @@ -1366,8 +1360,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename matrix_scalar_real_unary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e) const { + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e) { real_type t = real_type (); size_type size1 (e ().size1 ()); for (size_type i = 0; i < size1; ++ i) { @@ -1390,8 +1384,8 @@ namespace boost { namespace numeric { namespace ublas { typedef typename matrix_scalar_real_unary_functor::result_type result_type; template - BOOST_UBLAS_INLINE - result_type operator () (const matrix_expression &e) const { + static BOOST_UBLAS_INLINE + result_type apply (const matrix_expression &e) { real_type t = real_type (); size_type size1 (e ().size1 ()); for (size_type i = 0; i < size1; ++ i) { diff --git a/include/boost/numeric/ublas/matrix_assign.hpp b/include/boost/numeric/ublas/matrix_assign.hpp index e950a842..be4909e9 100644 --- a/include/boost/numeric/ublas/matrix_assign.hpp +++ b/include/boost/numeric/ublas/matrix_assign.hpp @@ -272,9 +272,9 @@ namespace boost { namespace numeric { namespace ublas { difference_type temp_size2 (size2); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- temp_size2 >= 0) - functor_type () (*it2, t), ++ it2; + functor_type::apply (*it2, t), ++ it2; #else - DD (temp_size2, 4, r, (functor_type () (*it2, t), ++ it2)); + DD (temp_size2, 4, r, (functor_type::apply (*it2, t), ++ it2)); #endif ++ it1; } @@ -300,9 +300,9 @@ namespace boost { namespace numeric { namespace ublas { difference_type temp_size1 (size1); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- temp_size1 >= 0) - functor_type () (*it1, t), ++ it1; + functor_type::apply (*it1, t), ++ it1; #else - DD (temp_size1, 4, r, (functor_type () (*it1, t), ++ it1)); + DD (temp_size1, 4, r, (functor_type::apply (*it1, t), ++ it1)); #endif ++ it2; } @@ -319,10 +319,10 @@ namespace boost { namespace numeric { namespace ublas { for (size_type i = 0; i < size1; ++ i) { #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type j = 0; j < size2; ++ j) - functor_type () (m (i, j), t); + functor_type::apply (m (i, j), t); #else size_type j (0); - DD (size2, 4, r, (functor_type () (m (i, j), t), ++ j)); + DD (size2, 4, r, (functor_type::apply (m (i, j), t), ++ j)); #endif } } @@ -338,10 +338,10 @@ namespace boost { namespace numeric { namespace ublas { for (size_type j = 0; j < size2; ++ j) { #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type i = 0; i < size1; ++ i) - functor_type () (m (i, j), t); + functor_type::apply (m (i, j), t); #else size_type i (0); - DD (size1, 4, r, (functor_type () (m (i, j), t), ++ i)); + DD (size1, 4, r, (functor_type::apply (m (i, j), t), ++ i)); #endif } } @@ -386,7 +386,7 @@ namespace boost { namespace numeric { namespace ublas { difference_type size2 (end (it1, iterator1_tag ()) - it2); #endif while (-- size2 >= 0) - functor_type () (*it2, t), ++ it2; + functor_type::apply (*it2, t), ++ it2; ++ it1; } } @@ -408,7 +408,7 @@ namespace boost { namespace numeric { namespace ublas { difference_type size1 (end (it2, iterator2_tag ()) - it1); #endif while (-- size1 >= 0) - functor_type () (*it1, t), ++ it1; + functor_type::apply (*it1, t), ++ it1; ++ it2; } } @@ -429,7 +429,7 @@ namespace boost { namespace numeric { namespace ublas { typename M::iterator2 it2_end (end (it1, iterator1_tag ())); #endif while (it2 != it2_end) - functor_type () (*it2, t), ++ it2; + functor_type::apply (*it2, t), ++ it2; ++ it1; } } @@ -450,7 +450,7 @@ namespace boost { namespace numeric { namespace ublas { typename M::iterator1 it1_end (end (it2, iterator2_tag ())); #endif while (it1 != it1_end) - functor_type () (*it1, t), ++ it1; + functor_type::apply (*it1, t), ++ it1; ++ it2; } } @@ -561,9 +561,9 @@ namespace boost { namespace numeric { namespace ublas { difference_type temp_size2 (size2); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- temp_size2 >= 0) - functor_type () (*it2, *it2e), ++ it2, ++ it2e; + functor_type::apply (*it2, *it2e), ++ it2, ++ it2e; #else - DD (temp_size2, 2, r, (functor_type () (*it2, *it2e), ++ it2, ++ it2e)); + DD (temp_size2, 2, r, (functor_type::apply (*it2, *it2e), ++ it2, ++ it2e)); #endif ++ it1, ++ it1e; } @@ -594,9 +594,9 @@ namespace boost { namespace numeric { namespace ublas { difference_type temp_size1 (size1); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- temp_size1 >= 0) - functor_type () (*it1, *it1e), ++ it1, ++ it1e; + functor_type::apply (*it1, *it1e), ++ it1, ++ it1e; #else - DD (temp_size1, 2, r, (functor_type () (*it1, *it1e), ++ it1, ++ it1e)); + DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e)); #endif ++ it2, ++ it2e; } @@ -613,10 +613,10 @@ namespace boost { namespace numeric { namespace ublas { for (size_type i = 0; i < size1; ++ i) { #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type j = 0; j < size2; ++ j) - functor_type () (m (i, j), e () (i, j)); + functor_type::apply (m (i, j), e () (i, j)); #else size_type j (0); - DD (size2, 2, r, (functor_type () (m (i, j), e () (i, j)), ++ j)); + DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j)); #endif } } @@ -632,10 +632,10 @@ namespace boost { namespace numeric { namespace ublas { for (size_type j = 0; j < size2; ++ j) { #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type i = 0; i < size1; ++ i) - functor_type () (m (i, j), e () (i, j)); + functor_type::apply (m (i, j), e () (i, j)); #else size_type i (0); - DD (size1, 2, r, (functor_type () (m (i, j), e () (i, j)), ++ i)); + DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i)); #endif } } @@ -713,7 +713,7 @@ namespace boost { namespace numeric { namespace ublas { #endif difference_type size2 (it2_end - it2); while (-- size2 >= 0) - functor1_type () (*it2, value_type (0)), ++ it2; + functor1_type::apply (*it2, value_type (0)), ++ it2; ++ it1; } } else { @@ -753,7 +753,7 @@ namespace boost { namespace numeric { namespace ublas { it2_size -= size2; if (boost::is_same::value) { while (-- size2 >= 0) - functor1_type () (*it2, value_type (0)), ++ it2; + functor1_type::apply (*it2, value_type (0)), ++ it2; } else { it2 += size2; } @@ -764,11 +764,11 @@ namespace boost { namespace numeric { namespace ublas { it2_size -= size2; it2e_size -= size2; while (-- size2 >= 0) - functor1_type () (*it2, *it2e), ++ it2, ++ it2e; + functor1_type::apply (*it2, *it2e), ++ it2, ++ it2e; size2 = it2_size; if (boost::is_same::value) { while (-- size2 >= 0) - functor1_type () (*it2, value_type (0)), ++ it2; + functor1_type::apply (*it2, value_type (0)), ++ it2; } else { it2 += size2; } @@ -786,7 +786,7 @@ namespace boost { namespace numeric { namespace ublas { #endif difference_type size2 (it2_end - it2); while (-- size2 >= 0) - functor1_type () (*it2, value_type (0)), ++ it2; + functor1_type::apply (*it2, value_type (0)), ++ it2; ++ it1; } } else { @@ -848,7 +848,7 @@ namespace boost { namespace numeric { namespace ublas { #endif difference_type size1 (it1_end - it1); while (-- size1 >= 0) - functor1_type () (*it1, value_type (0)), ++ it1; + functor1_type::apply (*it1, value_type (0)), ++ it1; ++ it2; } } else { @@ -888,7 +888,7 @@ namespace boost { namespace numeric { namespace ublas { it1_size -= size1; if (boost::is_same::value) { while (-- size1 >= 0) - functor1_type () (*it1, value_type (0)), ++ it1; + functor1_type::apply (*it1, value_type (0)), ++ it1; } else { it1 += size1; } @@ -899,11 +899,11 @@ namespace boost { namespace numeric { namespace ublas { it1_size -= size1; it1e_size -= size1; while (-- size1 >= 0) - functor1_type () (*it1, *it1e), ++ it1, ++ it1e; + functor1_type::apply (*it1, *it1e), ++ it1, ++ it1e; size1 = it1_size; if (boost::is_same::value) { while (-- size1 >= 0) - functor1_type () (*it1, value_type (0)), ++ it1; + functor1_type::apply (*it1, value_type (0)), ++ it1; } else { it1 += size1; } @@ -921,7 +921,7 @@ namespace boost { namespace numeric { namespace ublas { #endif difference_type size1 (it1_end - it1); while (-- size1 >= 0) - functor1_type () (*it1, value_type (0)), ++ it1; + functor1_type::apply (*it1, value_type (0)), ++ it1; ++ it2; } } else { @@ -1042,7 +1042,7 @@ namespace boost { namespace numeric { namespace ublas { while (true) { difference_type compare = it2_index - it2e_index; if (compare == 0) { - functor1_type () (*it2, *it2e); + functor1_type::apply (*it2, *it2e); ++ it2, ++ it2e; if (it2 != it2_end && it2e != it2e_end) { it2_index = it2.index2 (); @@ -1051,7 +1051,7 @@ namespace boost { namespace numeric { namespace ublas { break; } else if (compare < 0) { if (boost::is_same::value) { - functor1_type () (*it2, value_type (0)); + functor1_type::apply (*it2, value_type (0)); ++ it2; } else increment (it2, it2_end, - compare); @@ -1070,7 +1070,7 @@ namespace boost { namespace numeric { namespace ublas { } if (boost::is_same::value) { while (it2 != it2_end) { - functor1_type () (*it2, value_type (0)); + functor1_type::apply (*it2, value_type (0)); ++ it2; } } else { @@ -1087,7 +1087,7 @@ namespace boost { namespace numeric { namespace ublas { typename M::iterator2 it2_end (end (it1, iterator1_tag ())); #endif while (it2 != it2_end) { - functor1_type () (*it2, value_type (0)); + functor1_type::apply (*it2, value_type (0)); ++ it2; } ++ it1; @@ -1108,7 +1108,7 @@ namespace boost { namespace numeric { namespace ublas { typename M::iterator2 it2_end (end (it1, iterator1_tag ())); #endif while (it2 != it2_end) { - functor1_type () (*it2, value_type (0)); + functor1_type::apply (*it2, value_type (0)); ++ it2; } ++ it1; @@ -1169,7 +1169,7 @@ namespace boost { namespace numeric { namespace ublas { while (true) { difference_type compare = it1_index - it1e_index; if (compare == 0) { - functor1_type () (*it1, *it1e); + functor1_type::apply (*it1, *it1e); ++ it1, ++ it1e; if (it1 != it1_end && it1e != it1e_end) { it1_index = it1.index1 (); @@ -1178,7 +1178,7 @@ namespace boost { namespace numeric { namespace ublas { break; } else if (compare < 0) { if (boost::is_same::value) { - functor1_type () (*it1, value_type (0)); + functor1_type::apply (*it1, value_type (0)); ++ it1; } else increment (it1, it1_end, - compare); @@ -1197,7 +1197,7 @@ namespace boost { namespace numeric { namespace ublas { } if (boost::is_same::value) { while (it1 != it1_end) { - functor1_type () (*it1, value_type (0)); + functor1_type::apply (*it1, value_type (0)); ++ it1; } } else { @@ -1214,7 +1214,7 @@ namespace boost { namespace numeric { namespace ublas { typename M::iterator1 it1_end (end (it2, iterator2_tag ())); #endif while (it1 != it1_end) { - functor1_type () (*it1, value_type (0)); + functor1_type::apply (*it1, value_type (0)); ++ it1; } ++ it2; @@ -1235,7 +1235,7 @@ namespace boost { namespace numeric { namespace ublas { typename M::iterator1 it1_end (end (it2, iterator2_tag ())); #endif while (it1 != it1_end) { - functor1_type () (*it1, value_type (0)); + functor1_type::apply (*it1, value_type (0)); ++ it1; } ++ it2; @@ -1317,7 +1317,7 @@ namespace boost { namespace numeric { namespace ublas { difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), size_type (end (it1e, iterator1_tag ()) - it2e))); #endif while (-- size2 >= 0) - functor_type () (*it2, *it2e), ++ it2, ++ it2e; + functor_type::apply (*it2, *it2e), ++ it2, ++ it2e; ++ it1, ++ it1e; } } @@ -1343,7 +1343,7 @@ namespace boost { namespace numeric { namespace ublas { difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), size_type (end (it2e, iterator2_tag ()) - it1e))); #endif while (-- size1 >= 0) - functor_type () (*it1, *it1e), ++ it1, ++ it1e; + functor_type::apply (*it1, *it1e), ++ it1, ++ it1e; ++ it2, ++ it2e; } } @@ -1370,7 +1370,7 @@ namespace boost { namespace numeric { namespace ublas { difference_type size2 (BOOST_UBLAS_SAME (end (it1, iterator1_tag ()) - it2, end (it1e, iterator1_tag ()) - it2e)); #endif while (-- size2 >= 0) - functor1_type () (*it2, *it2e), ++ it2, ++ it2e; + functor1_type::apply (*it2, *it2e), ++ it2, ++ it2e; ++ it1, ++ it1e; } } @@ -1397,7 +1397,7 @@ namespace boost { namespace numeric { namespace ublas { difference_type size1 (BOOST_UBLAS_SAME (end (it2, iterator2_tag ()) - it1, end (it2e, iterator2_tag ()) - it1e)); #endif while (-- size1 >= 0) - functor1_type () (*it1, *it1e), ++ it1, ++ it1e; + functor1_type::apply (*it1, *it1e), ++ it1, ++ it1e; ++ it2, ++ it2e; } } @@ -1440,7 +1440,7 @@ namespace boost { namespace numeric { namespace ublas { while (true) { difference_type compare = it2_index - it2e_index; if (compare == 0) { - functor1_type () (*it2, *it2e); + functor1_type::apply (*it2, *it2e); ++ it2, ++ it2e; if (it2 != it2_end && it2e != it2e_end) { it2_index = it2.index2 (); @@ -1565,7 +1565,7 @@ namespace boost { namespace numeric { namespace ublas { while (true) { difference_type compare = it1_index - it1e_index; if (compare == 0) { - functor1_type () (*it1, *it1e); + functor1_type::apply (*it1, *it1e); ++ it1, ++ it1e; if (it1 != it1_end && it1e != it1e_end) { it1_index = it1.index1 (); diff --git a/include/boost/numeric/ublas/matrix_expression.hpp b/include/boost/numeric/ublas/matrix_expression.hpp index f023de5e..d61861c5 100644 --- a/include/boost/numeric/ublas/matrix_expression.hpp +++ b/include/boost/numeric/ublas/matrix_expression.hpp @@ -548,7 +548,7 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { - return functor_type () (e1_ (i), e2_ (j)); + return functor_type::apply (e1_ (i), e2_ (j)); } // Closure comparison @@ -705,9 +705,9 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE const_reference operator * () const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (*it1_, t2_); + return functor_type::apply (*it1_, t2_); #else - return functor_type () (*it1_, *it2_); + return functor_type::apply (*it1_, *it2_); #endif } @@ -875,9 +875,9 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE const_reference operator * () const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (t1_, *it2_); + return functor_type::apply (t1_, *it2_); #else - return functor_type () (*it1_, *it2_); + return functor_type::apply (*it1_, *it2_); #endif } @@ -1001,7 +1001,8 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef matrix result_type; + // ISSUE matrix is arbitary temporary type + typedef matrix result_type; #endif }; @@ -1071,7 +1072,7 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { - return functor_type () (e_ (i, j)); + return functor_type::apply (e_ (i, j)); } // Closure comparison @@ -1189,7 +1190,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (*it_); + return functor_type::apply (*it_); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION @@ -1328,7 +1329,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (*it_); + return functor_type::apply (*it_); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION @@ -1436,7 +1437,7 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef matrix result_type; + typedef typename E::matrix_temporary_type result_type; #endif }; @@ -1550,7 +1551,7 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { - return functor_type () (e_ (j, i)); + return functor_type::apply (e_ (j, i)); } BOOST_UBLAS_INLINE reference operator () (size_type i, size_type j) { @@ -1673,7 +1674,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (*it_); + return functor_type::apply (*it_); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION @@ -1812,7 +1813,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (*it_); + return functor_type::apply (*it_); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION @@ -1921,7 +1922,7 @@ namespace boost { namespace numeric { namespace ublas { // #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; // #else -// typedef matrix result_type; +// typedef typename E::matrix_temporary_type result_type; // #endif }; @@ -2011,7 +2012,7 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { - return functor_type () (e1_ (i, j), e2_ (i, j)); + return functor_type::apply (e1_ (i, j), e2_ (i, j)); } // Closure comparison @@ -2136,7 +2137,7 @@ namespace boost { namespace numeric { namespace ublas { } BOOST_UBLAS_INLINE value_type dereference (dense_random_access_iterator_tag) const { - return functor_type () (*it1_, *it2_); + return functor_type::apply (*it1_, *it2_); } // Packed specializations @@ -2174,7 +2175,7 @@ namespace boost { namespace numeric { namespace ublas { if (it2_.index1 () == i_) t2 = *it2_; } - return functor_type () (t1, t2); + return functor_type::apply (t1, t2); } // Sparse specializations @@ -2228,7 +2229,7 @@ namespace boost { namespace numeric { namespace ublas { if (it2_.index1 () == i_) t2 = *it2_; } - return functor_type () (t1, t2); + return functor_type::apply (t1, t2); } // Arithmetic @@ -2402,7 +2403,7 @@ namespace boost { namespace numeric { namespace ublas { } BOOST_UBLAS_INLINE value_type dereference (dense_random_access_iterator_tag) const { - return functor_type () (*it1_, *it2_); + return functor_type::apply (*it1_, *it2_); } // Packed specializations @@ -2440,7 +2441,7 @@ namespace boost { namespace numeric { namespace ublas { if (it2_.index2 () == j_) t2 = *it2_; } - return functor_type () (t1, t2); + return functor_type::apply (t1, t2); } // Sparse specializations @@ -2494,7 +2495,7 @@ namespace boost { namespace numeric { namespace ublas { if (it2_.index2 () == j_) t2 = *it2_; } - return functor_type () (t1, t2); + return functor_type::apply (t1, t2); } // Arithmetic @@ -2652,7 +2653,7 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef matrix result_type; + typedef typename E1::matrix_temporary_type result_type; #endif }; @@ -2704,12 +2705,12 @@ namespace boost { namespace numeric { namespace ublas { return expression_type (e1 (), e2 ()); } - template + template class matrix_binary_scalar1: - public matrix_expression > { + public matrix_expression > { public: #ifndef BOOST_UBLAS_NO_PROXY_SHORTCUTS - BOOST_UBLAS_USING matrix_expression >::operator (); + BOOST_UBLAS_USING matrix_expression >::operator (); #endif typedef typename E2::size_type size_type; typedef typename E2::difference_type difference_type; @@ -2722,9 +2723,9 @@ namespace boost { namespace numeric { namespace ublas { typedef E1 expression1_type; typedef E2 expression2_type; typedef F functor_type; - typedef E1 expression1_closure_type; + typedef C1 expression1_closure_type; typedef typename E2::const_closure_type expression2_closure_type; - typedef matrix_binary_scalar1 self_type; + typedef matrix_binary_scalar1 self_type; public: typedef const self_type const_closure_type; typedef const_closure_type closure_type; @@ -2749,36 +2750,23 @@ namespace boost { namespace numeric { namespace ublas { return e2_.size2 (); } -#ifndef BOOST_UBLAS_NESTED_CLASS_DR45 - private: -#endif - // Expression accessors - BOOST_UBLAS_INLINE - const expression1_closure_type &expression1 () const { - return e1_; - } - BOOST_UBLAS_INLINE - const expression2_closure_type &expression2 () const { - return e2_; - } - public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { - return functor_type () (e1_, e2_ (i, j)); + return functor_type::apply (expression1_type (e1_), e2_ (i, j)); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_binary_scalar1 &mbs1) const { - return (*this).expression1 ().same_closure (mbs1.expression1 ()) && - (*this).expression2 ().same_closure (mbs1.expression2 ()); + return (*this).e1_.same_closure (mbs1.e1_) && + (*this).e2_.same_closure (mbs1.e2_); } // Iterator types private: - typedef typename E1::value_type const_iterator1_type; + typedef expression1_type const_iterator1_type; typedef typename E2::const_iterator1 const_iterator21_type; typedef typename E2::const_iterator2 const_iterator22_type; @@ -2809,7 +2797,7 @@ namespace boost { namespace numeric { namespace ublas { #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator1 (*this, it21.index1 (), it21.index2 ()); #else - return const_iterator1 (*this, e1_, it21); + return const_iterator1 (*this, const_iterator1_type (e1_), it21); #endif } BOOST_UBLAS_INLINE @@ -2818,7 +2806,7 @@ namespace boost { namespace numeric { namespace ublas { #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator2 (*this, it22.index1 (), it22.index2 ()); #else - return const_iterator2 (*this, e1_, it22); + return const_iterator2 (*this, const_iterator1_type (e1_), it22); #endif } @@ -2888,7 +2876,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (it1_, *it2_); + return functor_type::apply (it1_, *it2_); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION @@ -3035,7 +3023,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (it1_, *it2_); + return functor_type::apply (it1_, *it2_); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION @@ -3144,32 +3132,45 @@ namespace boost { namespace numeric { namespace ublas { expression2_closure_type e2_; }; - template + template struct matrix_binary_scalar1_traits { - typedef matrix_binary_scalar1, E2, F> expression_type; + typedef matrix_binary_scalar1 expression_type; // allow E1 to be builtin type #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef matrix result_type; + typedef typename E2::matrix_temporary_type result_type; #endif }; +#ifdef BOOST_UBLAS_USE_SCALAR_ET + // (s * m) [i] = scalar_expression * m [i] + template + BOOST_UBLAS_INLINE + typename matrix_binary_scalar1_traits >::result_type + operator * (const scalar_expression &e1, + const matrix_expression &e2) { + typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar1_traits >::expression_type expression_type; + return expression_type (e1 (), e2 ()); + } +#endif + // (t * m) [i] [j] = t * m [i] [j] template BOOST_UBLAS_INLINE - typename matrix_binary_scalar1_traits >::result_type + typename matrix_binary_scalar1_traits, scalar_reference >::result_type operator * (const T1 &e1, const matrix_expression &e2) { - typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar1_traits >::expression_type expression_type; + typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar1_traits, scalar_reference >::expression_type expression_type; return expression_type (e1, e2 ()); } - template + + template class matrix_binary_scalar2: - public matrix_expression > { + public matrix_expression > { public: #ifndef BOOST_UBLAS_NO_PROXY_SHORTCUTS - BOOST_UBLAS_USING matrix_expression >::operator (); + BOOST_UBLAS_USING matrix_expression >::operator (); #endif typedef typename E1::size_type size_type; typedef typename E1::difference_type difference_type; @@ -3183,8 +3184,8 @@ namespace boost { namespace numeric { namespace ublas { typedef E2 expression2_type; typedef F functor_type; typedef typename E1::const_closure_type expression1_closure_type; - typedef E2 expression2_closure_type; - typedef matrix_binary_scalar2 self_type; + typedef C2 expression2_closure_type; + typedef matrix_binary_scalar2 self_type; public: typedef const self_type const_closure_type; typedef const_closure_type closure_type; @@ -3209,38 +3210,25 @@ namespace boost { namespace numeric { namespace ublas { return e1_.size2 (); } -#ifndef BOOST_UBLAS_NESTED_CLASS_DR45 - private: -#endif - // Expression accessors - BOOST_UBLAS_INLINE - const expression1_closure_type &expression1 () const { - return e1_; - } - BOOST_UBLAS_INLINE - const expression2_closure_type &expression2 () const { - return e2_; - } - public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { - return functor_type () (e1_ (i, j), e2_); + return functor_type::apply (e1_ (i, j), expression2_type (e2_)); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_binary_scalar2 &mbs2) const { - return (*this).expression1 ().same_closure (mbs2.expression1 ()) && - (*this).expression2 ().same_closure (mbs2.expression2 ()); + return (*this).e1_.same_closure (mbs2.e1_) && + (*this).e2_.same_closure (mbs2.e2_); } // Iterator types private: typedef typename E1::const_iterator1 const_iterator11_type; typedef typename E1::const_iterator2 const_iterator12_type; - typedef typename E2::value_type const_iterator2_type; + typedef expression2_type const_iterator2_type; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR @@ -3269,7 +3257,7 @@ namespace boost { namespace numeric { namespace ublas { #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator1 (*this, it11.index1 (), it11.index2 ()); #else - return const_iterator1 (*this, it11, e2_); + return const_iterator1 (*this, it11, const_iterator2_type (e2_)); #endif } BOOST_UBLAS_INLINE @@ -3278,7 +3266,7 @@ namespace boost { namespace numeric { namespace ublas { #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator2 (*this, it12.index1 (), it12.index2 ()); #else - return const_iterator2 (*this, it12, e2_); + return const_iterator2 (*this, it12, const_iterator2_type (e2_)); #endif } @@ -3348,7 +3336,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (*it1_, it2_); + return functor_type::apply (*it1_, it2_); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION @@ -3495,7 +3483,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (*it1_, it2_); + return functor_type::apply (*it1_, it2_); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION @@ -3604,36 +3592,59 @@ namespace boost { namespace numeric { namespace ublas { expression2_closure_type e2_; }; - template + template struct matrix_binary_scalar2_traits { - typedef matrix_binary_scalar2, F> expression_type; + typedef matrix_binary_scalar2 expression_type; // allow E2 to be builtin type #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef matrix result_type; + typedef typename E1::matrix_temporary_type result_type; #endif }; +#ifdef BOOST_UBLAS_USE_SCALAR_ET + // (m * s) [i] = m [i] * scalar_expression + template + BOOST_UBLAS_INLINE + typename matrix_binary_scalar2_traits >::result_type + operator * (const matrix_expression &e1, + const scalar_expression &e2) { + typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar2_traits >::expression_type expression_type; + return expression_type (e1 (), e2 ()); + } + + // (m / s) [i] = m [i] / scalar_expression + template + BOOST_UBLAS_INLINE + typename matrix_binary_scalar2_traits >::result_type + operator / (const matrix_expression &e1, + const scalar_expression &e2) { + typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar2_traits >::expression_type expression_type; + return expression_type (e1 (), e2 ()); + } +#endif + // (m * t) [i] [j] = m [i] [j] * t template BOOST_UBLAS_INLINE - typename matrix_binary_scalar2_traits >::result_type + typename matrix_binary_scalar2_traits, scalar_reference >::result_type operator * (const matrix_expression &e1, const T2 &e2) { - typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar2_traits >::expression_type expression_type; + typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar2_traits, scalar_reference >::expression_type expression_type; return expression_type (e1 (), e2); } // (m / t) [i] [j] = m [i] [j] / t template BOOST_UBLAS_INLINE - typename matrix_binary_scalar2_traits >::result_type + typename matrix_binary_scalar2_traits, scalar_reference >::result_type operator / (const matrix_expression &e1, const T2 &e2) { - typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar2_traits >::expression_type expression_type; + typedef BOOST_UBLAS_TYPENAME matrix_binary_scalar2_traits, scalar_reference >::expression_type expression_type; return expression_type (e1 (), e2); } + template class matrix_vector_binary1: public vector_expression > { @@ -3691,7 +3702,7 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i) const { - return functor_type () (e1_, e2_, i); + return functor_type::apply (e1_, e2_, i); } // Closure comparison @@ -3777,17 +3788,17 @@ namespace boost { namespace numeric { namespace ublas { #elif BOOST_UBLAS_USE_ITERATING difference_type size = BOOST_UBLAS_SAME (mvb.expression1 ().size2 (), mvb.expression2 ().size ()); #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (size, it1_.begin (), e2_begin_); + return functor_type::apply (size, it1_.begin (), e2_begin_); #else - return functor_type () (size, it1_.begin (), mvb.expression2 ().begin ()); + return functor_type::apply (size, it1_.begin (), mvb.expression2 ().begin ()); #endif #else difference_type size = BOOST_UBLAS_SAME (mvb.expression1 ().size2 (), mvb.expression2 ().size ()); if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (size, it1_.begin (), e2_begin_); + return functor_type::apply (size, it1_.begin (), e2_begin_); #else - return functor_type () (size, it1_.begin (), mvb.expression2 ().begin ()); + return functor_type::apply (size, it1_.begin (), mvb.expression2 ().begin ()); #endif else return mvb (index ()); @@ -3798,14 +3809,14 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type dereference (packed_random_access_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (it1_.begin (), it1_.end (), e2_begin_, e2_end_); + return functor_type::apply (it1_.begin (), it1_.end (), e2_begin_, e2_end_); #else const self_type &mvb = (*this) (); #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION - return functor_type () (it1_.begin (), it1_.end (), + return functor_type::apply (it1_.begin (), it1_.end (), mvb.expression2 ().begin (), mvb.expression2 ().end ()); #else - return functor_type () (boost::numeric::ublas::begin (it1_, iterator1_tag ()), + return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), boost::numeric::ublas::end (it1_, iterator1_tag ()), mvb.expression2 ().begin (), mvb.expression2 ().end ()); #endif @@ -3816,14 +3827,14 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type dereference (sparse_bidirectional_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (it1_.begin (), it1_.end (), e2_begin_, e2_end_, sparse_bidirectional_iterator_tag ()); + return functor_type::apply (it1_.begin (), it1_.end (), e2_begin_, e2_end_, sparse_bidirectional_iterator_tag ()); #else const self_type &mvb = (*this) (); #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION - return functor_type () (it1_.begin (), it1_.end (), + return functor_type::apply (it1_.begin (), it1_.end (), mvb.expression2 ().begin (), mvb.expression2 ().end (), sparse_bidirectional_iterator_tag ()); #else - return functor_type () (boost::numeric::ublas::begin (it1_, iterator1_tag ()), + return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), boost::numeric::ublas::end (it1_, iterator1_tag ()), mvb.expression2 ().begin (), mvb.expression2 ().end (), sparse_bidirectional_iterator_tag ()); #endif @@ -3943,7 +3954,7 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef vector result_type; + typedef typename E1::vector_temporary_type result_type; #endif }; @@ -4094,7 +4105,7 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type j) const { - return functor_type () (e1_, e2_, j); + return functor_type::apply (e1_, e2_, j); } // Closure comparison @@ -4180,17 +4191,17 @@ namespace boost { namespace numeric { namespace ublas { #elif BOOST_UBLAS_USE_ITERATING difference_type size = BOOST_UBLAS_SAME (mvb.expression2 ().size1 (), mvb.expression1 ().size ()); #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (size, e1_begin_, it2_.begin ()); + return functor_type::apply (size, e1_begin_, it2_.begin ()); #else - return functor_type () (size, mvb.expression1 ().begin (), it2_.begin ()); + return functor_type::apply (size, mvb.expression1 ().begin (), it2_.begin ()); #endif #else difference_type size = BOOST_UBLAS_SAME (mvb.expression2 ().size1 (), mvb.expression1 ().size ()); if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (size, e1_begin_, it2_.begin ()); + return functor_type::apply (size, e1_begin_, it2_.begin ()); #else - return functor_type () (size, mvb.expression1 ().begin (), it2_.begin ()); + return functor_type::apply (size, mvb.expression1 ().begin (), it2_.begin ()); #endif else return mvb (index ()); @@ -4201,14 +4212,14 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type dereference (packed_random_access_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (e1_begin_, e1_end_, it2_.begin (), it2_.end ()); + return functor_type::apply (e1_begin_, e1_end_, it2_.begin (), it2_.end ()); #else const self_type &mvb = (*this) (); #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION - return functor_type () (mvb.expression1 ().begin (), mvb.expression1 ().end (), + return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (), it2_.begin (), it2_.end ()); #else - return functor_type () (mvb.expression1 ().begin (), mvb.expression1 ().end (), + return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (), boost::numeric::ublas::begin (it2_, iterator2_tag ()), boost::numeric::ublas::end (it2_, iterator2_tag ())); #endif @@ -4219,14 +4230,14 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type dereference (sparse_bidirectional_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (e1_begin_, e1_end_, it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); + return functor_type::apply (e1_begin_, e1_end_, it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); #else const self_type &mvb = (*this) (); #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION - return functor_type () (mvb.expression1 ().begin (), mvb.expression1 ().end (), + return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (), it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); #else - return functor_type () (mvb.expression1 ().begin (), mvb.expression1 ().end (), + return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (), boost::numeric::ublas::begin (it2_, iterator2_tag ()), boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ()); #endif @@ -4346,7 +4357,7 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef vector result_type; + typedef typename E2::vector_temporary_type result_type; #endif }; @@ -4503,7 +4514,7 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { - return functor_type () (e1_, e2_, i, j); + return functor_type::apply (e1_, e2_, i, j); } // Closure comparison @@ -4625,17 +4636,17 @@ namespace boost { namespace numeric { namespace ublas { #elif BOOST_UBLAS_USE_ITERATING difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ()); #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (size, it1_.begin (), it2_begin_); + return functor_type::apply (size, it1_.begin (), it2_begin_); #else - return functor_type () (size, it1_.begin (), it2_.begin ()); + return functor_type::apply (size, it1_.begin (), it2_.begin ()); #endif #else difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ()); if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (size, it1_.begin (), it2_begin_); + return functor_type::apply (size, it1_.begin (), it2_begin_); #else - return functor_type () (size, it1_.begin (), it2_.begin ()); + return functor_type::apply (size, it1_.begin (), it2_.begin ()); #endif else return mmb (index1 (), index2 ()); @@ -4646,14 +4657,14 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type dereference (packed_random_access_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (it1_.begin (), it1_.end (), + return functor_type::apply (it1_.begin (), it1_.end (), it2_begin_, it2_end_, packed_random_access_iterator_tag ()); #else #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION - return functor_type () (it1_.begin (), it1_.end (), + return functor_type::apply (it1_.begin (), it1_.end (), it2_.begin (), it2_.end (), packed_random_access_iterator_tag ()); #else - return functor_type () (boost::numeric::ublas::begin (it1_, iterator1_tag ()), + return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), boost::numeric::ublas::end (it1_, iterator1_tag ()), boost::numeric::ublas::begin (it2_, iterator2_tag ()), boost::numeric::ublas::end (it2_, iterator2_tag ()), packed_random_access_iterator_tag ()); @@ -4665,14 +4676,14 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type dereference (sparse_bidirectional_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (it1_.begin (), it1_.end (), + return functor_type::apply (it1_.begin (), it1_.end (), it2_begin_, it2_end_, sparse_bidirectional_iterator_tag ()); #else #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION - return functor_type () (it1_.begin (), it1_.end (), + return functor_type::apply (it1_.begin (), it1_.end (), it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); #else - return functor_type () (boost::numeric::ublas::begin (it1_, iterator1_tag ()), + return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), boost::numeric::ublas::end (it1_, iterator1_tag ()), boost::numeric::ublas::begin (it2_, iterator2_tag ()), boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ()); @@ -4854,17 +4865,17 @@ namespace boost { namespace numeric { namespace ublas { #elif BOOST_UBLAS_USE_ITERATING difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ()); #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (size, it1_begin_, it2_.begin ()); + return functor_type::apply (size, it1_begin_, it2_.begin ()); #else - return functor_type () (size, it1_.begin (), it2_.begin ()); + return functor_type::apply (size, it1_.begin (), it2_.begin ()); #endif #else difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ()); if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (size, it1_begin_, it2_.begin ()); + return functor_type::apply (size, it1_begin_, it2_.begin ()); #else - return functor_type () (size, it1_.begin (), it2_.begin ()); + return functor_type::apply (size, it1_.begin (), it2_.begin ()); #endif else return mmb (index1 (), index2 ()); @@ -4875,14 +4886,14 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type dereference (packed_random_access_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (it1_begin_, it1_end_, + return functor_type::apply (it1_begin_, it1_end_, it2_.begin (), it2_.end (), packed_random_access_iterator_tag ()); #else #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION - return functor_type () (it1_.begin (), it1_.end (), + return functor_type::apply (it1_.begin (), it1_.end (), it2_.begin (), it2_.end (), packed_random_access_iterator_tag ()); #else - return functor_type () (boost::numeric::ublas::begin (it1_, iterator1_tag ()), + return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), boost::numeric::ublas::end (it1_, iterator1_tag ()), boost::numeric::ublas::begin (it2_, iterator2_tag ()), boost::numeric::ublas::end (it2_, iterator2_tag ()), packed_random_access_iterator_tag ()); @@ -4894,14 +4905,14 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type dereference (sparse_bidirectional_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING - return functor_type () (it1_begin_, it1_end_, + return functor_type::apply (it1_begin_, it1_end_, it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); #else #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION - return functor_type () (it1_.begin (), it1_.end (), + return functor_type::apply (it1_.begin (), it1_.end (), it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); #else - return functor_type () (boost::numeric::ublas::begin (it1_, iterator1_tag ()), + return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), boost::numeric::ublas::end (it1_, iterator1_tag ()), boost::numeric::ublas::begin (it2_, iterator2_tag ()), boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ()); @@ -5065,7 +5076,7 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef matrix result_type; + typedef typename E1::matrix_temporary_type result_type; #endif }; @@ -5161,7 +5172,7 @@ namespace boost { namespace numeric { namespace ublas { template class matrix_scalar_unary: - public scalar_expression { + public scalar_expression > { public: typedef E expression_type; typedef F functor_type; @@ -5188,7 +5199,7 @@ namespace boost { namespace numeric { namespace ublas { public: BOOST_UBLAS_INLINE operator value_type () const { - return functor_type () (e_); + return functor_type::apply (e_); } private: diff --git a/include/boost/numeric/ublas/vector_assign.hpp b/include/boost/numeric/ublas/vector_assign.hpp index 84f21243..e69fa9dc 100644 --- a/include/boost/numeric/ublas/vector_assign.hpp +++ b/include/boost/numeric/ublas/vector_assign.hpp @@ -108,9 +108,9 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_CHECK (v.end () - it == size, bad_size ()); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) - functor_type () (*it, t), ++ it; + functor_type::apply (*it, t), ++ it; #else - DD (size, 4, r, (functor_type () (*it, t), ++ it)); + DD (size, 4, r, (functor_type::apply (*it, t), ++ it)); #endif } // Indexing case @@ -123,10 +123,10 @@ namespace boost { namespace numeric { namespace ublas { size_type size (v.size ()); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type i = 0; i < size; ++ i) - functor_type () (v (i), t); + functor_type::apply (v (i), t); #else size_type i (0); - DD (size, 4, r, (functor_type () (v (i), t), ++ i)); + DD (size, 4, r, (functor_type::apply (v (i), t), ++ i)); #endif } @@ -159,7 +159,7 @@ namespace boost { namespace numeric { namespace ublas { typename V::iterator it (v.begin ()); difference_type size (v.end () - it); while (-- size >= 0) - functor_type () (*it, t), ++ it; + functor_type::apply (*it, t), ++ it; } // Sparse (proxy) case template @@ -170,7 +170,7 @@ namespace boost { namespace numeric { namespace ublas { typename V::iterator it (v.begin ()); typename V::iterator it_end (v.end ()); while (it != it_end) - functor_type () (*it, t), ++ it; + functor_type::apply (*it, t), ++ it; } // Dispatcher @@ -266,9 +266,9 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_CHECK (e ().end () - ite == size, bad_size ()); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) - functor_type () (*it, *ite), ++ it, ++ ite; + functor_type::apply (*it, *ite), ++ it, ++ ite; #else - DD (size, 2, r, (functor_type () (*it, *ite), ++ it, ++ ite)); + DD (size, 2, r, (functor_type::apply (*it, *ite), ++ it, ++ ite)); #endif } // Indexing case @@ -281,10 +281,10 @@ namespace boost { namespace numeric { namespace ublas { size_type size (BOOST_UBLAS_SAME (v.size (), e ().size ())); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type i = 0; i < size; ++ i) - functor_type () (v (i), e () (i)); + functor_type::apply (v (i), e () (i)); #else size_type i (0); - DD (size, 2, r, (functor_type () (v (i), e () (i)), ++ i)); + DD (size, 2, r, (functor_type::apply (v (i), e () (i)), ++ i)); #endif } @@ -345,7 +345,7 @@ namespace boost { namespace numeric { namespace ublas { it_size -= size; if (boost::is_same::value) { while (-- size >= 0) - functor_type () (*it, value_type (0)), ++ it; + functor_type::apply (*it, value_type (0)), ++ it; } else { it += size; } @@ -355,11 +355,11 @@ namespace boost { namespace numeric { namespace ublas { it_size -= size; ite_size -= size; while (-- size >= 0) - functor_type () (*it, *ite), ++ it, ++ ite; + functor_type::apply (*it, *ite), ++ it, ++ ite; size = it_size; if (boost::is_same::value) { while (-- size >= 0) - functor_type () (*it, value_type (0)), ++ it; + functor_type::apply (*it, value_type (0)), ++ it; } else { it += size; } @@ -433,7 +433,7 @@ namespace boost { namespace numeric { namespace ublas { while (true) { difference_type compare = it_index - ite_index; if (compare == 0) { - functor_type () (*it, *ite); + functor_type::apply (*it, *ite); ++ it, ++ ite; if (it != it_end && ite != ite_end) { it_index = it.index (); @@ -442,7 +442,7 @@ namespace boost { namespace numeric { namespace ublas { break; } else if (compare < 0) { if (boost::is_same::value) { - functor_type () (*it, value_type (0)); + functor_type::apply (*it, value_type (0)); ++ it; } else increment (it, it_end, - compare); @@ -462,7 +462,7 @@ namespace boost { namespace numeric { namespace ublas { if (boost::is_same::value) { while (it != it_end) { - functor_type () (*it, value_type (0)); + functor_type::apply (*it, value_type (0)); ++ it; } } else { @@ -511,7 +511,7 @@ namespace boost { namespace numeric { namespace ublas { typename V::iterator it (v.begin ()); typename E::iterator ite (e ().begin ()); while (-- size >= 0) - functor_type () (*it, *ite), ++ it, ++ ite; + functor_type::apply (*it, *ite), ++ it, ++ ite; } // Packed (proxy) case template @@ -542,7 +542,7 @@ namespace boost { namespace numeric { namespace ublas { it_size -= size; ite_size -= size; while (-- size >= 0) - functor_type () (*it, *ite), ++ it, ++ ite; + functor_type::apply (*it, *ite), ++ it, ++ ite; } // Sparse proxy case template @@ -567,7 +567,7 @@ namespace boost { namespace numeric { namespace ublas { while (true) { difference_type compare = it_index - ite_index; if (compare == 0) { - functor_type () (*it, *ite); + functor_type::apply (*it, *ite); ++ it, ++ ite; if (it != it_end && ite != ite_end) { it_index = it.index (); diff --git a/include/boost/numeric/ublas/vector_expression.hpp b/include/boost/numeric/ublas/vector_expression.hpp index 63b4de88..b5ee3386 100644 --- a/include/boost/numeric/ublas/vector_expression.hpp +++ b/include/boost/numeric/ublas/vector_expression.hpp @@ -65,11 +65,90 @@ namespace boost { namespace numeric { namespace ublas { } }; + template + class scalar_reference: + public scalar_expression > { + public: + typedef T value_type; +#ifndef BOOST_UBLAS_CT_REFERENCE_BASE_TYPEDEFS + typedef const value_type &const_reference; + typedef value_type &reference; +#else + typedef const value_type &const_reference; + typedef typename boost::mpl::if_, + const_reference, + value_type &>::type reference; +#endif + private: + typedef scalar_reference self_type; + public: + typedef const self_type const_closure_type; + typedef const_closure_type closure_type; + + // Construction and destruction + BOOST_UBLAS_INLINE + scalar_reference (): + t_ (nil_) {} + BOOST_UBLAS_INLINE + explicit scalar_reference (reference t): + t_ (t) {} + + BOOST_UBLAS_INLINE + operator value_type () const { + return t_; + } + + // Assignment + BOOST_UBLAS_INLINE + scalar_reference &operator = (const scalar_reference &s) { + t_ = s.t_; + return *this; + } + template + BOOST_UBLAS_INLINE + scalar_reference &operator = (const scalar_expression &ae) { + t_ = ae; + return *this; + } + + // Closure comparison + BOOST_UBLAS_INLINE + bool same_closure (const scalar_reference &sr) const { + return &t_ == &sr.t_; + } + + private: + reference t_; + static value_type nil_; + }; + + template + typename scalar_reference::value_type scalar_reference::nil_ + = BOOST_UBLAS_TYPENAME scalar_reference::value_type (); + template class scalar_value: public scalar_expression > { public: typedef T value_type; +#ifndef BOOST_UBLAS_CT_REFERENCE_BASE_TYPEDEFS + typedef const value_type &const_reference; + typedef value_type &reference; +#else + typedef const value_type &const_reference; + typedef typename boost::mpl::if_, + const_reference, + value_type &>::type reference; +#endif + private: + typedef scalar_value self_type; + public: +#ifndef BOOST_UBLAS_CT_REFERENCE_BASE_TYPEDEFS + typedef const scalar_const_reference const_closure_type; +#else + typedef const scalar_reference const_closure_type; +#endif + typedef scalar_reference closure_type; // Construction and destruction BOOST_UBLAS_INLINE @@ -84,50 +163,29 @@ namespace boost { namespace numeric { namespace ublas { return t_; } + // Assignment + BOOST_UBLAS_INLINE + scalar_value &operator = (const scalar_value &s) { + t_ = s.t_; + return *this; + } + template + BOOST_UBLAS_INLINE + scalar_value &operator = (const scalar_expression &ae) { + t_ = ae; + return *this; + } + // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const scalar_value &sv) const { - return this == &sv; // shortcut for &t_ == &sv.t_ + return this == &sv; // self closing on instances value } private: value_type t_; }; - template - class scalar_const_reference: - public scalar_expression > { - public: - typedef T value_type; - - // Construction and destruction - BOOST_UBLAS_INLINE - scalar_const_reference (): - t_ (nil_) {} - BOOST_UBLAS_INLINE - scalar_const_reference (const value_type &t): - t_ (t) {} - - BOOST_UBLAS_INLINE - operator value_type () const { - return t_; - } - - // Closure comparison - BOOST_UBLAS_INLINE - bool same_closure (const scalar_const_reference &sr) const { - return &t_ == &sr.t_; - } - - private: - const value_type &t_; - static const value_type nil_; - }; - - template - const typename scalar_const_reference::value_type scalar_const_reference::nil_ - = BOOST_UBLAS_TYPENAME scalar_const_reference::value_type (); - // Base class for Vector Expressions - see the Barton Nackman trick template @@ -222,33 +280,33 @@ namespace boost { namespace numeric { namespace ublas { #endif }; - template + template class vector_reference: - public vector_expression > { + public vector_expression > { public: #ifndef BOOST_UBLAS_NO_PROXY_SHORTCUTS - BOOST_UBLAS_USING vector_expression >::operator (); + BOOST_UBLAS_USING vector_expression >::operator (); #endif - typedef typename E::size_type size_type; - typedef typename E::difference_type difference_type; - typedef typename E::value_type value_type; + typedef typename T::size_type size_type; + typedef typename T::difference_type difference_type; + typedef typename T::value_type value_type; #ifndef BOOST_UBLAS_CT_REFERENCE_BASE_TYPEDEFS - typedef typename E::const_reference const_reference; - typedef typename E::reference reference; + typedef typename T::const_reference const_reference; + typedef typename T::reference reference; #else - typedef typename E::const_reference const_reference; - typedef typename boost::mpl::if_, - typename E::const_reference, - typename E::reference>::type reference; + typedef typename T::const_reference const_reference; + typedef typename boost::mpl::if_, + typename T::const_reference, + typename T::reference>::type reference; #endif private: - typedef vector_reference self_type; + typedef vector_reference self_type; public: - typedef E refered_type; + typedef T refered_type; typedef const self_type const_closure_type; typedef const_closure_type closure_type; - typedef typename E::storage_category storage_category; - typedef typename E::simd_category simd_category; + typedef typename T::storage_category storage_category; + typedef typename T::simd_category simd_category; // Construction and destruction BOOST_UBLAS_INLINE @@ -378,13 +436,13 @@ namespace boost { namespace numeric { namespace ublas { // Iterator types #ifndef BOOST_UBLAS_CT_REFERENCE_BASE_TYPEDEFS - typedef typename E::const_iterator const_iterator; - typedef typename E::iterator iterator; + typedef typename T::const_iterator const_iterator; + typedef typename T::iterator iterator; #else - typedef typename E::const_iterator const_iterator; - typedef typename boost::mpl::if_, - typename E::const_iterator, - typename E::iterator>::type iterator; + typedef typename T::const_iterator const_iterator; + typedef typename boost::mpl::if_, + typename T::const_iterator, + typename T::iterator>::type iterator; #endif // Element lookup @@ -454,10 +512,10 @@ namespace boost { namespace numeric { namespace ublas { static refered_type nil_; }; - template - typename vector_reference::refered_type vector_reference::nil_ + template + typename vector_reference::refered_type vector_reference::nil_ #ifdef BOOST_UBLAS_STATIC_OLD_INIT - = BOOST_UBLAS_TYPENAME vector_reference::refered_type (); + = BOOST_UBLAS_TYPENAME vector_reference::refered_type () #endif ; @@ -521,7 +579,7 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i) const { - return functor_type () (e_ (i)); + return functor_type::apply (e_ (i)); } BOOST_UBLAS_INLINE reference operator () (size_type i) { @@ -531,7 +589,7 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { - return functor_type () (e_ [i]); + return functor_type::apply (e_ [i]); } BOOST_UBLAS_INLINE reference operator [] (size_type i) { @@ -631,7 +689,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (*it_); + return functor_type::apply (*it_); } // Index @@ -702,7 +760,7 @@ namespace boost { namespace numeric { namespace ublas { // #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; // #else -// typedef vector result_type; +// typedef typename E::vector_temporary_type result_type; // #endif }; @@ -821,12 +879,12 @@ namespace boost { namespace numeric { namespace ublas { // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i) const { - return functor_type () (e1_ (i), e2_ (i)); + return functor_type::apply (e1_ (i), e2_ (i)); } BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { - return functor_type () (e1_ [i], e2_ [i]); + return functor_type::apply (e1_ [i], e2_ [i]); } // Closure comparison @@ -915,7 +973,7 @@ namespace boost { namespace numeric { namespace ublas { } BOOST_UBLAS_INLINE value_type dereference (dense_random_access_iterator_tag) const { - return functor_type () (*it1_, *it2_); + return functor_type::apply (*it1_, *it2_); } // Packed specializations @@ -949,7 +1007,7 @@ namespace boost { namespace numeric { namespace ublas { if (it2_ != it2_end_) if (it2_.index () == i_) t2 = *it2_; - return functor_type () (t1, t2); + return functor_type::apply (t1, t2); } // Sparse specializations @@ -999,7 +1057,7 @@ namespace boost { namespace numeric { namespace ublas { if (it2_ != it2_end_) if (it2_.index () == i_) t2 = *it2_; - return functor_type () (t1, t2); + return functor_type::apply (t1, t2); } // Arithmetic @@ -1111,7 +1169,7 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef vector result_type; + typedef typename E1::vector_temporary_type result_type; #endif }; @@ -1163,12 +1221,13 @@ namespace boost { namespace numeric { namespace ublas { return expression_type (e1 (), e2 ()); } - template + + template class vector_binary_scalar1: - public vector_expression > { + public vector_expression > { public: #ifndef BOOST_UBLAS_NO_PROXY_SHORTCUTS - BOOST_UBLAS_USING vector_expression >::operator (); + BOOST_UBLAS_USING vector_expression >::operator (); #endif typedef typename E2::size_type size_type; typedef typename E2::difference_type difference_type; @@ -1177,12 +1236,12 @@ namespace boost { namespace numeric { namespace ublas { typedef const_reference reference; private: typedef const value_type *const_pointer; + typedef F functor_type; typedef E1 expression1_type; typedef E2 expression2_type; - typedef F functor_type; - typedef E1 expression1_closure_type; + typedef C1 expression1_closure_type; typedef typename E2::const_closure_type expression2_closure_type; - typedef vector_binary_scalar1 self_type; + typedef vector_binary_scalar1 self_type; public: typedef const self_type const_closure_type; typedef const_closure_type closure_type; @@ -1202,40 +1261,29 @@ namespace boost { namespace numeric { namespace ublas { return e2_.size (); } - private: - // Expression accesors - BOOST_UBLAS_INLINE - const expression1_closure_type &expression1 () const { - return e1_; - } - BOOST_UBLAS_INLINE - const expression2_closure_type &expression2 () const { - return e2_; - } - public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i) const { - return functor_type () (e1_, e2_ (i)); + return functor_type::apply (expression1_type (e1_), e2_ (i)); } BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { - return functor_type () (e1_, e2_ [i]); + return functor_type::apply (expression1_type (e1_), e2_ [i]); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const vector_binary_scalar1 &vbs1) const { - return (*this).expression1 ().same_closure (vbs1.expression1 ()) && - (*this).expression2 ().same_closure (vbs1.expression2 ()); + return (*this).e1_.same_closure (vbs1.e1_) && + (*this).e2_.same_closure (vbs1.e2_); } // Iterator types private: - typedef typename E1::value_type const_iterator1_type; - typedef typename E2::const_iterator const_iterator2_type; + typedef expression1_type const_iterator1_type; + typedef typename expression2_type::const_iterator const_iterator2_type; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR @@ -1253,7 +1301,7 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2_type it (e2_.find (i)); return const_iterator (*this, it.index ()); #else - return const_iterator (*this, e1_, e2_.find (i)); + return const_iterator (*this, const_iterator1_type (e1_), e2_.find (i)); #endif } @@ -1321,7 +1369,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (it1_, *it2_); + return functor_type::apply (it1_, *it2_); } // Index @@ -1392,32 +1440,45 @@ namespace boost { namespace numeric { namespace ublas { expression2_closure_type e2_; }; - template + template struct vector_binary_scalar1_traits { - typedef vector_binary_scalar1, E2, F> expression_type; + typedef vector_binary_scalar1 expression_type; // allow E1 to be builtin type #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef vector result_type; + typedef typename E2::vector_temporary_type result_type; #endif }; +#ifdef BOOST_UBLAS_USE_SCALAR_ET + // (s * v) [i] = scalar_expression * v [i] + template + BOOST_UBLAS_INLINE + typename vector_binary_scalar1_traits >::result_type + operator * (const scalar_expression &e1, + const vector_expression &e2) { + typedef BOOST_UBLAS_TYPENAME vector_binary_scalar1_traits >::expression_type expression_type; + return expression_type (e1 (), e2 ()); + } +#endif + // (t * v) [i] = t * v [i] template BOOST_UBLAS_INLINE - typename vector_binary_scalar1_traits >::result_type + typename vector_binary_scalar1_traits, scalar_reference >::result_type operator * (const T1 &e1, const vector_expression &e2) { - typedef BOOST_UBLAS_TYPENAME vector_binary_scalar1_traits >::expression_type expression_type; + typedef BOOST_UBLAS_TYPENAME vector_binary_scalar1_traits, scalar_reference >::expression_type expression_type; return expression_type (e1, e2 ()); } - template + + template class vector_binary_scalar2: - public vector_expression > { + public vector_expression > { public: #ifndef BOOST_UBLAS_NO_PROXY_SHORTCUTS - BOOST_UBLAS_USING vector_expression >::operator (); + BOOST_UBLAS_USING vector_expression >::operator (); #endif typedef typename E1::size_type size_type; typedef typename E1::difference_type difference_type; @@ -1426,13 +1487,12 @@ namespace boost { namespace numeric { namespace ublas { typedef const_reference reference; private: typedef const value_type *const_pointer; - typedef const_pointer pointer; + typedef F functor_type; typedef E1 expression1_type; typedef E2 expression2_type; - typedef F functor_type; typedef typename E1::const_closure_type expression1_closure_type; - typedef E2 expression2_closure_type; - typedef vector_binary_scalar2 self_type; + typedef C2 expression2_closure_type; + typedef vector_binary_scalar2 self_type; public: typedef const self_type const_closure_type; typedef const_closure_type closure_type; @@ -1452,40 +1512,29 @@ namespace boost { namespace numeric { namespace ublas { return e1_.size (); } - private: - // Expression accesors - BOOST_UBLAS_INLINE - const expression1_closure_type &expression1 () const { - return e1_; - } - BOOST_UBLAS_INLINE - const expression2_closure_type &expression2 () const { - return e2_; - } - public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i) const { - return functor_type () (e1_ (i), e2_); + return functor_type::apply (e1_ (i), expression2_type (e2_)); } BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { - return functor_type () (e1_ [i], e2_); + return functor_type::apply (e1_ [i], expression2_type (e2_)); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const vector_binary_scalar2 &vbs2) const { - return (*this).expression1 ().same_closure (vbs2.expression1 ()) && - (*this).expression2 ().same_closure (vbs2.expression2 ()); + return (*this).e1_.same_closure (vbs2.e1_) && + (*this).e2_.same_closure (vbs2.e2_); } // Iterator types private: - typedef typename E1::const_iterator const_iterator1_type; - typedef typename E2::value_type const_iterator2_type; + typedef typename expression1_type::const_iterator const_iterator1_type; + typedef expression2_type const_iterator2_type; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR @@ -1503,7 +1552,7 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1_type it (e1_.find (i)); return const_iterator (*this, it.index ()); #else - return const_iterator (*this, e1_.find (i), e2_); + return const_iterator (*this, e1_.find (i), const_iterator2_type (e2_)); #endif } @@ -1571,7 +1620,7 @@ namespace boost { namespace numeric { namespace ublas { // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { - return functor_type () (*it1_, it2_); + return functor_type::apply (*it1_, it2_); } // Index @@ -1642,39 +1691,62 @@ namespace boost { namespace numeric { namespace ublas { expression2_closure_type e2_; }; - template + template struct vector_binary_scalar2_traits { - typedef vector_binary_scalar2, F> expression_type; + typedef vector_binary_scalar2 expression_type; // allow E2 to be builtin type #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else - typedef vector result_type; + typedef typename E1::vector_temporary_type result_type; #endif }; +#ifdef BOOST_UBLAS_USE_SCALAR_ET + // (v * s) [i] = v [i] * scalar_expression + template + BOOST_UBLAS_INLINE + typename vector_binary_scalar2_traits >::result_type + operator * (const vector_expression &e1, + const scalar_expression &e2) { + typedef BOOST_UBLAS_TYPENAME vector_binary_scalar2_traits >::expression_type expression_type; + return expression_type (e1 (), e2 ()); + } + + // (v / s) [i] = v [i] / scalar_expression + template + BOOST_UBLAS_INLINE + typename vector_binary_scalar2_traits >::result_type + operator / (const vector_expression &e1, + const scalar_expression &e2) { + typedef BOOST_UBLAS_TYPENAME vector_binary_scalar2_traits >::expression_type expression_type; + return expression_type (e1 (), e2 ()); + } +#endif + // (v * t) [i] = v [i] * t template BOOST_UBLAS_INLINE - typename vector_binary_scalar2_traits >::result_type + typename vector_binary_scalar2_traits, scalar_reference >::result_type operator * (const vector_expression &e1, const T2 &e2) { - typedef BOOST_UBLAS_TYPENAME vector_binary_scalar2_traits >::expression_type expression_type; + typedef BOOST_UBLAS_TYPENAME vector_binary_scalar2_traits, scalar_reference >::expression_type expression_type; return expression_type (e1 (), e2); } // (v / t) [i] = v [i] / t template BOOST_UBLAS_INLINE - typename vector_binary_scalar2_traits >::result_type + typename vector_binary_scalar2_traits, scalar_reference >::result_type operator / (const vector_expression &e1, const T2 &e2) { - typedef BOOST_UBLAS_TYPENAME vector_binary_scalar2_traits >::expression_type expression_type; + typedef BOOST_UBLAS_TYPENAME vector_binary_scalar2_traits, scalar_reference >::expression_type expression_type; return expression_type (e1 (), e2); } + template class vector_scalar_unary: - public scalar_expression { + public scalar_expression > { public: typedef typename F::size_type size_type; typedef typename F::difference_type difference_type; @@ -1684,7 +1756,10 @@ namespace boost { namespace numeric { namespace ublas { typedef F functor_type; typedef typename E::const_closure_type expression_closure_type; typedef typename E::const_iterator::iterator_category iterator_category; + typedef vector_scalar_unary self_type; public: + typedef const self_type const_closure_type; + typedef const_closure_type closure_type; typedef unknown_storage_tag storage_category; // Construction and destruction @@ -1715,29 +1790,29 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type evaluate (dense_random_access_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INDEXING - return functor_type () (e_); + return functor_type::apply (e_); #elif BOOST_UBLAS_USE_ITERATING difference_type size = e_.size (); - return functor_type () (size, e_.begin ()); + return functor_type::apply (size, e_.begin ()); #else difference_type size = e_.size (); if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) - return functor_type () (size, e_.begin ()); + return functor_type::apply (size, e_.begin ()); else - return functor_type () (e_); + return functor_type::apply (e_); #endif } // Packed bidirectional specialization BOOST_UBLAS_INLINE value_type evaluate (packed_random_access_iterator_tag) const { - return functor_type () (e_.begin (), e_.end ()); + return functor_type::apply (e_.begin (), e_.end ()); } // Sparse bidirectional specialization BOOST_UBLAS_INLINE value_type evaluate (sparse_bidirectional_iterator_tag) const { - return functor_type () (e_.begin (), e_.end ()); + return functor_type::apply (e_.begin (), e_.end ()); } private: @@ -1806,7 +1881,7 @@ namespace boost { namespace numeric { namespace ublas { template class vector_scalar_binary: - public scalar_expression { + public scalar_expression > { public: BOOST_STATIC_CONSTANT (unsigned, complexity = 1); typedef typename F::size_type size_type; @@ -1820,7 +1895,10 @@ namespace boost { namespace numeric { namespace ublas { typedef typename E2::const_closure_type expression2_closure_type; typedef typename iterator_restrict_traits::iterator_category iterator_category; + typedef vector_scalar_binary self_type; public: + typedef const self_type const_closure_type; + typedef const_closure_type closure_type; typedef unknown_storage_tag storage_category; // Construction and destruction @@ -1853,29 +1931,29 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE value_type evaluate (dense_random_access_iterator_tag) const { #ifdef BOOST_UBLAS_USE_INDEXING - return functor_type () (e1_, e2_); + return functor_type::apply (e1_, e2_); #elif BOOST_UBLAS_USE_ITERATING difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ()); - return functor_type () (size, e1_.begin (), e2_.begin ()); + return functor_type::apply (size, e1_.begin (), e2_.begin ()); #else difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ()); if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) - return functor_type () (size, e1_.begin (), e2_.begin ()); + return functor_type::apply (size, e1_.begin (), e2_.begin ()); else - return functor_type () (e1_, e2_); + return functor_type::apply (e1_, e2_); #endif } // Packed bidirectional specialization BOOST_UBLAS_INLINE value_type evaluate (packed_random_access_iterator_tag) const { - return functor_type () (e1_.begin (), e1_.end (), e2_.begin (), e2_.end ()); + return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end ()); } // Sparse bidirectional specialization BOOST_UBLAS_INLINE value_type evaluate (sparse_bidirectional_iterator_tag) const { - return functor_type () (e1_.begin (), e1_.end (), e2_.begin (), e2_.end (), sparse_bidirectional_iterator_tag ()); + return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end (), sparse_bidirectional_iterator_tag ()); } private: