aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/util/XprHelper.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-12-22 22:51:08 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-12-22 22:51:08 +0100
commiteaaba30cacf078335ad41314bf1e4ce993f0b3b4 (patch)
tree61156273b56dc19fc4e661a5aeb42d8e6112a307 /Eigen/src/Core/util/XprHelper.h
parente182e9c6166840b8db44e0be459a2e26d26fda0f (diff)
parenteeec7d842e05394703c42e7569230835f7842089 (diff)
merge with default branch
Diffstat (limited to 'Eigen/src/Core/util/XprHelper.h')
-rw-r--r--Eigen/src/Core/util/XprHelper.h53
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