bugfix for a = a * b; when a has to be resized
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 5301f48..32b526e 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h
@@ -536,6 +536,9 @@ resizeLike(other); } + template<typename MatrixType, typename OtherDerived, bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0> + struct ei_matrix_set_selector; + /** \internal Copies the value of the expression \a other into \c *this with automatic resizing. * * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), @@ -550,8 +553,8 @@ template<typename OtherDerived> EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other) { - _resize_to_match(other); - return Base::operator=(other); + ei_matrix_set_selector<Matrix,OtherDerived>::run(*this,other.derived()); + return *this; } /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which @@ -600,6 +603,20 @@ } }; +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +template<typename MatrixType, typename OtherDerived> +struct Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ei_matrix_set_selector<MatrixType,OtherDerived,true> +{ + static void run(MatrixType& dst, const OtherDerived& src) { dst._set_noalias(src.eval()); } +}; + +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +template<typename MatrixType, typename OtherDerived> +struct Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ei_matrix_set_selector<MatrixType,OtherDerived,false> +{ + static void run(MatrixType& dst, const OtherDerived& src) { dst._set_noalias(src); } +}; + /** \defgroup matrixtypedefs Global matrix typedefs * * \ingroup Core_Module
diff --git a/test/product_large.cpp b/test/product_large.cpp index 77ae7b5..9b53e7b 100644 --- a/test/product_large.cpp +++ b/test/product_large.cpp
@@ -42,4 +42,10 @@ m = (v+v).asDiagonal() * m; VERIFY_IS_APPROX(m, MatrixXf::Constant(N,3,2)); } + + { + // test deferred resizing in Matrix::operator= + MatrixXf a = MatrixXf::Random(10,4), b = MatrixXf::Random(4,10), c = a; + VERIFY_IS_APPROX((a = a * b), (c * b).eval()); + } }