when copying a ReturnByValue into a MatrixBase, first eval it to a PlainMatrixType.

This allows to limit the number of instantiations of the big template method evalTo.
Also allows to get rid of the dummy MatrixBase::resize().
See "TODO" comment.
This commit is contained in:
Benoit Jacob 2009-09-26 22:48:16 -04:00
parent e82ab8a5dd
commit 924b55e9a9
2 changed files with 16 additions and 15 deletions

View File

@ -190,19 +190,6 @@ template<typename Derived> class MatrixBase
* i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
/** Only plain matrices, not expressions may be resized; therefore the only useful resize method is
* Matrix::resize(). The present method only asserts that the new size equals the old size, and does
* nothing else.
*/
void resize(int size)
{ ei_assert(size == this->size() && "MatrixBase::resize() does not actually allow to resize."); }
/** Only plain matrices, not expressions may be resized; therefore the only useful resize method is
* Matrix::resize(). The present method only asserts that the new size equals the old size, and does
* nothing else.
*/
void resize(int rows, int cols)
{ ei_assert(rows == this->rows() && cols == this->cols() && "MatrixBase::resize() does not actually allow to resize."); }
#ifndef EIGEN_PARSED_BY_DOXYGEN
/** \internal the plain matrix type corresponding to this expression. Note that is not necessarily
* exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const

View File

@ -65,8 +65,22 @@ template<typename Derived>
template<typename OtherDerived>
Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
{
other.evalTo(derived());
return derived();
// Here we evaluate to a temporary matrix tmp, which we then copy. The main purpose
// of this is to limit the number of instantiations of the template method evalTo<Destination>():
// we only instantiate for PlainMatrixType.
// Notice that this behaviour is specific to this operator in MatrixBase. The corresponding operator in class Matrix
// does not evaluate into a temporary first.
// TODO find a way to avoid evaluating into a temporary in the cases that matter. At least Block<> matters
// for the implementation of blocked algorithms.
// Should we:
// - try a trick like for the products, where the destination is abstracted as an array with stride?
// - or just add an operator in class Block, so we get a separate instantiation there (bad) but at least not more
// than that, and at least that's easy to make work?
// - or, since here we're talking about a compromise between code size and performance, let the user choose?
// Not obvious: many users will never find out about this feature, and it's hard to find a good API.
PlainMatrixType tmp;
other.evalTo(tmp);
return derived() = tmp;
}
#endif // EIGEN_RETURNBYVALUE_H