diff options
author | Gael Guennebaud <g.gael@free.fr> | 2009-12-22 22:51:08 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2009-12-22 22:51:08 +0100 |
commit | eaaba30cacf078335ad41314bf1e4ce993f0b3b4 (patch) | |
tree | 61156273b56dc19fc4e661a5aeb42d8e6112a307 /Eigen/src/Core/util/XprHelper.h | |
parent | e182e9c6166840b8db44e0be459a2e26d26fda0f (diff) | |
parent | eeec7d842e05394703c42e7569230835f7842089 (diff) |
merge with default branch
Diffstat (limited to 'Eigen/src/Core/util/XprHelper.h')
-rw-r--r-- | Eigen/src/Core/util/XprHelper.h | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 6d6540acc..6d4a5c7bc 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -28,10 +28,11 @@ // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ - struct ei_empty_struct{char _ei_dummy_;}; - #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct + #define EIGEN_EMPTY_STRUCT_CTOR(X) \ + EIGEN_STRONG_INLINE X() {} \ + EIGEN_STRONG_INLINE X(const X&) {} #else - #define EIGEN_EMPTY_STRUCT + #define EIGEN_EMPTY_STRUCT_CTOR(X) #endif //classes inheriting ei_no_assignment_operator don't generate a default operator=. @@ -45,10 +46,10 @@ class ei_no_assignment_operator * can be accessed using value() and setValue(). * Otherwise, this class is an empty structure and value() just returns the template parameter Value. */ -template<int Value> class ei_int_if_dynamic EIGEN_EMPTY_STRUCT +template<int Value> class ei_int_if_dynamic { public: - ei_int_if_dynamic() {} + EIGEN_EMPTY_STRUCT_CTOR(ei_int_if_dynamic) explicit ei_int_if_dynamic(int) {} static int value() { return Value; } void setValue(int) {} @@ -214,8 +215,35 @@ template<typename T> struct ei_plain_matrix_type_row_major > type; }; +// we should be able to get rid of this one too template<typename T> struct ei_must_nest_by_value { enum { ret = false }; }; -template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; }; + +/** +* The reference selector for template expressions. The idea is that we don't +* need to use references for expressions since they are light weight proxy +* objects which should generate no copying overhead. +**/ +template <typename T> +struct ei_ref_selector +{ + typedef T type; +}; + +/** +* Matrices on the other hand side should only be copied, when it is sure +* we gain by copying (see arithmetic cost check and eval before nesting flag). +* Note: This is an optimization measure that comprises potential (though little) +* to create erroneous code. Any user, utilizing ei_nested outside of +* Eigen needs to take care that no references to temporaries are +* stored or that this potential danger is at least communicated +* to the user. +**/ +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > +{ + typedef Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType; + typedef MatrixType const& type; +}; /** \internal Determines how a given expression should be nested into another one. * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be @@ -241,15 +269,12 @@ template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::ty CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost), CostNoEval = (n-1) * int(ei_traits<T>::CoeffReadCost) }; + typedef typename ei_meta_if< - ei_must_nest_by_value<T>::ret, - T, - typename ei_meta_if< - (int(ei_traits<T>::Flags) & EvalBeforeNestingBit) - || ( int(CostEval) <= int(CostNoEval) ), + ( int(ei_traits<T>::Flags) & EvalBeforeNestingBit ) || + ( int(CostEval) <= int(CostNoEval) ), PlainMatrixType, - const T& - >::ret + typename ei_ref_selector<T>::type >::ret type; }; @@ -302,7 +327,7 @@ template<typename ExpressionType> struct HNormalizedReturnType { ei_traits<ExpressionType>::ColsAtCompileTime==1 ? SizeMinusOne : 1, ei_traits<ExpressionType>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne; typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<ExpressionType>::Scalar>, - NestByValue<StartMinusOne> > Type; + StartMinusOne > Type; }; template<typename XprType, typename CastType> struct ei_cast_return_type |