--- a/Eigen/src/Core/Array.h +++ a/Eigen/src/Core/Array.h @@ -41,16 +41,25 @@ */ namespace internal { template struct traits > : traits > { typedef ArrayXpr XprKind; typedef ArrayBase > XprBase; }; + +template +struct evaluator > +{ + typedef Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> xpr_type; + typedef xpr_type type; + const type& result; + evaluator(const xpr_type& xpr) : result(xpr) {} +}; } template class Array : public PlainObjectBase > { public: --- a/Eigen/src/Core/ArrayWrapper.h +++ a/Eigen/src/Core/ArrayWrapper.h @@ -38,16 +38,25 @@ namespace internal { template struct traits > : public traits::type > { typedef ArrayXpr XprKind; }; + +template +struct evaluator > +{ + typedef ArrayWrapper xpr_type; + typedef ArrayWrapper::type> type; + type result; + evaluator(const xpr_type& xpr) : result(xpr.nestedXpr()) {} +}; } template class ArrayWrapper : public ArrayBase > { public: typedef ArrayBase Base; EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper) @@ -104,16 +113,18 @@ class ArrayWrapper : public ArrayBase(index, x); } template inline void evalTo(Dest& dst) const { dst = m_expression; } + const NestedExpressionType nestedXpr() const { return m_expression; } + protected: const NestedExpressionType m_expression; }; /** \class MatrixWrapper * \ingroup Core_Module * * \brief Expression of an array as a mathematical vector or matrix @@ -126,16 +137,25 @@ class ArrayWrapper : public ArrayBase struct traits > : public traits::type > { typedef MatrixXpr XprKind; }; + +template +struct evaluator > +{ + typedef MatrixWrapper xpr_type; + typedef MatrixWrapper::type> type; + type result; + evaluator(const xpr_type& xpr) : result(xpr.nestedXpr()) {} +}; } template class MatrixWrapper : public MatrixBase > { public: typedef MatrixBase > Base; EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper) @@ -189,13 +209,15 @@ class MatrixWrapper : public MatrixBase< } template inline void writePacket(Index index, const PacketScalar& x) { m_expression.const_cast_derived().template writePacket(index, x); } + const NestedExpressionType nestedXpr() const { return m_expression; } + protected: const NestedExpressionType m_expression; }; #endif // EIGEN_ARRAYWRAPPER_H --- a/Eigen/src/Core/Assign.h +++ a/Eigen/src/Core/Assign.h @@ -513,42 +513,59 @@ EIGEN_STRONG_INLINE Derived& DenseBase::type >::value, bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0, bool NeedToTranspose = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime && ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1) | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&". // revert to || as soon as not needed anymore. (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1)) && int(Derived::SizeAtCompileTime) != 1> struct assign_selector; template -struct assign_selector { +struct assign_selector { EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } }; template -struct assign_selector { +struct assign_selector { EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } }; template -struct assign_selector { +struct assign_selector { EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } }; template -struct assign_selector { +struct assign_selector { EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } }; +template +struct assign_selector { + EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(evaluator(other).result); } +}; +template +struct assign_selector { + EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(evaluator(other).result.eval()); } +}; +template +struct assign_selector { + EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(evaluator(other.transpose()).result); } +}; +template +struct assign_selector { + EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(evaluator(other.transpose()).result.eval()); } +}; } // end namespace internal template template EIGEN_STRONG_INLINE Derived& DenseBase::operator=(const DenseBase& other) { return internal::assign_selector::run(derived(), other.derived()); --- a/Eigen/src/Core/Matrix.h +++ a/Eigen/src/Core/Matrix.h @@ -125,16 +125,26 @@ struct traits::ret, CoeffReadCost = NumTraits::ReadCost, Options = _Options, InnerStrideAtCompileTime = 1, OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime }; }; + +template +struct evaluator > +{ + typedef Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> xpr_type; + typedef xpr_type type; + const type& result; + evaluator(const xpr_type& xpr) : result(xpr) {} +}; + } template class Matrix : public PlainObjectBase > { public: --- a/Eigen/src/Core/PlainObjectBase.h +++ a/Eigen/src/Core/PlainObjectBase.h @@ -478,17 +478,17 @@ class PlainObjectBase : public internal: template EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase& other) { // I don't think we need this resize call since the lazyAssign will anyways resize // and lazyAssign will be called by the assign selector. //_resize_to_match(other); // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because // it wouldn't allow to copy a row-vector into a column-vector. - return internal::assign_selector::run(this->derived(), other.derived()); + return internal::assign_selector::type>::value,false>::run(this->derived(), other.derived()); } template EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if::type* = 0) { eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); m_storage.resize(rows*cols,rows,cols); --- a/Eigen/src/Core/Transpose.h +++ a/Eigen/src/Core/Transpose.h @@ -55,16 +55,25 @@ struct traits > : MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime, Flags = int(_MatrixTypeNested::Flags & ~NestByRefBit) ^ RowMajorBit, CoeffReadCost = _MatrixTypeNested::CoeffReadCost, InnerStrideAtCompileTime = inner_stride_at_compile_time::ret, OuterStrideAtCompileTime = outer_stride_at_compile_time::ret }; }; + +template +struct evaluator > +{ + typedef Transpose xpr_type; + typedef Transpose::type> type; + type result; + evaluator(const xpr_type& xpr) : result(xpr.nestedExpression()) {} +}; } template class TransposeImpl; template class Transpose : public TransposeImpl::StorageKind> { public: --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ a/Eigen/src/Core/util/ForwardDeclarations.h @@ -22,22 +22,26 @@ // You should have received a copy of the GNU Lesser General Public // License and a copy of the GNU General Public License along with // Eigen. If not, see . #ifndef EIGEN_FORWARDDECLARATIONS_H #define EIGEN_FORWARDDECLARATIONS_H namespace internal { + template struct traits; template struct has_direct_access { enum { ret = (traits::Flags & DirectAccessBit) ? 1 : 0 }; }; + +template struct evaluator {}; + } // end namespace internal template struct NumTraits; template struct EigenBase; template class DenseBase; template::Flags & DirectAccessBit) ? DirectAccessors