Do not bypass aliasing in sparse e assignments

This commit is contained in:
Gael Guennebaud 2014-07-01 11:48:49 +02:00
parent c401167712
commit 7ffd55c980
2 changed files with 17 additions and 6 deletions

View File

@ -143,7 +143,7 @@ template<typename Derived>
template<typename OtherDerived> template<typename OtherDerived>
inline Derived& SparseMatrixBase<Derived>::operator=(const SparseMatrixBase<OtherDerived>& other) inline Derived& SparseMatrixBase<Derived>::operator=(const SparseMatrixBase<OtherDerived>& other)
{ {
internal::call_assignment_no_alias(derived(), other.derived()); internal::call_assignment/*_no_alias*/(derived(), other.derived());
return derived(); return derived();
} }

View File

@ -649,7 +649,13 @@ class SparseMatrix
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
check_template_parameters(); check_template_parameters();
#ifndef EIGEN_TEST_EVALUATORS
*this = other.derived(); *this = other.derived();
#else
const bool needToTranspose = (Flags & RowMajorBit) != (internal::evaluator<OtherDerived>::Flags & RowMajorBit);
if (needToTranspose) *this = other.derived();
else internal::call_assignment_no_alias(*this, other.derived());
#endif
} }
/** Constructs a sparse matrix from the sparse selfadjoint view \a other */ /** Constructs a sparse matrix from the sparse selfadjoint view \a other */
@ -722,6 +728,7 @@ class SparseMatrix
return *this; return *this;
} }
#ifndef EIGEN_TEST_EVALUATORS
#ifndef EIGEN_PARSED_BY_DOXYGEN #ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename Lhs, typename Rhs> template<typename Lhs, typename Rhs>
inline SparseMatrix& operator=(const SparseSparseProduct<Lhs,Rhs>& product) inline SparseMatrix& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
@ -738,6 +745,7 @@ class SparseMatrix
inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other) inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other)
{ return Base::operator=(other.derived()); } { return Base::operator=(other.derived()); }
#endif #endif
#endif // EIGEN_TEST_EVALUATORS
template<typename OtherDerived> template<typename OtherDerived>
EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other); EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other);
@ -1174,7 +1182,9 @@ EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Opt
else else
{ {
if(other.isRValue()) if(other.isRValue())
{
initAssignment(other.derived()); initAssignment(other.derived());
}
// there is no special optimization // there is no special optimization
return Base::operator=(other.derived()); return Base::operator=(other.derived());
} }
@ -1336,12 +1346,13 @@ struct evaluator<SparseMatrix<_Scalar,_Options,_Index> >
Flags = SparseMatrixType::Flags Flags = SparseMatrixType::Flags
}; };
evaluator(const SparseMatrixType &mat) : m_matrix(mat) {} evaluator() : m_matrix(0) {}
evaluator(const SparseMatrixType &mat) : m_matrix(&mat) {}
operator SparseMatrixType&() { return m_matrix.const_cast_derived(); } operator SparseMatrixType&() { return m_matrix->const_cast_derived(); }
operator const SparseMatrixType&() const { return m_matrix; } operator const SparseMatrixType&() const { return *m_matrix; }
const SparseMatrixType &m_matrix; const SparseMatrixType *m_matrix;
}; };
} }