mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-03-07 18:27:40 +08:00
bug #884: Copy constructor of Ref shall never malloc, constructing from other RefBase shall only malloc if the memory layout is incompatible.
This commit is contained in:
parent
e404841235
commit
12d59465cb
@ -232,6 +232,15 @@ template<typename TPlainObjectType, int Options, typename StrideType> class Ref<
|
||||
construct(expr.derived(), typename Traits::template match<Derived>::type());
|
||||
}
|
||||
|
||||
inline Ref(const Ref& other) : Base(other) {
|
||||
// copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
|
||||
}
|
||||
|
||||
template<typename OtherRef>
|
||||
inline Ref(const RefBase<OtherRef>& other) {
|
||||
construct(other.derived(), typename Traits::template match<OtherRef>::type());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template<typename Expression>
|
||||
|
@ -21,7 +21,7 @@
|
||||
// discard stack allocation as that too bypasses malloc
|
||||
#define EIGEN_STACK_ALLOCATION_LIMIT 0
|
||||
// any heap allocation will raise an assert
|
||||
#define EIGEN_NO_MALLOC
|
||||
#define EIGEN_RUNTIME_NO_MALLOC
|
||||
|
||||
#include "main.h"
|
||||
#include <Eigen/Cholesky>
|
||||
@ -183,9 +183,11 @@ template<typename MatrixType> void test_reference(const MatrixType& m) {
|
||||
enum { Flag = MatrixType::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor};
|
||||
enum { TransposeFlag = !MatrixType::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor};
|
||||
typename MatrixType::Index rows = m.rows(), cols=m.cols();
|
||||
typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Flag > MatrixX;
|
||||
typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, TransposeFlag> MatrixXT;
|
||||
// Dynamic reference:
|
||||
typedef Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Flag > > Ref;
|
||||
typedef Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, TransposeFlag> > RefT;
|
||||
typedef Eigen::Ref<const MatrixX > Ref;
|
||||
typedef Eigen::Ref<const MatrixXT > RefT;
|
||||
|
||||
Ref r1(m);
|
||||
Ref r2(m.block(rows/3, cols/4, rows/2, cols/2));
|
||||
@ -195,10 +197,30 @@ template<typename MatrixType> void test_reference(const MatrixType& m) {
|
||||
VERIFY_RAISES_ASSERT(RefT r5(m));
|
||||
VERIFY_RAISES_ASSERT(Ref r6(m.transpose()));
|
||||
VERIFY_RAISES_ASSERT(Ref r7(Scalar(2) * m));
|
||||
|
||||
// Copy constructors shall also never malloc
|
||||
Ref r8 = r1;
|
||||
RefT r9 = r3;
|
||||
|
||||
// Initializing from a compatible Ref shall also never malloc
|
||||
Eigen::Ref<const MatrixX, Unaligned, Stride<Dynamic, Dynamic> > r10=r8, r11=m;
|
||||
|
||||
// Initializing from an incompatible Ref will malloc:
|
||||
typedef Eigen::Ref<const MatrixX, Aligned> RefAligned;
|
||||
VERIFY_RAISES_ASSERT(RefAligned r12=r10);
|
||||
VERIFY_RAISES_ASSERT(Ref r13=r10); // r10 has more dynamic strides
|
||||
|
||||
}
|
||||
|
||||
void test_nomalloc()
|
||||
{
|
||||
// create some dynamic objects
|
||||
Eigen::MatrixXd M1 = MatrixXd::Random(3,3);
|
||||
Ref<const MatrixXd> R1 = 2.0*M1; // Ref requires temporary
|
||||
|
||||
// from here on prohibit malloc:
|
||||
Eigen::internal::set_is_malloc_allowed(false);
|
||||
|
||||
// check that our operator new is indeed called:
|
||||
VERIFY_RAISES_ASSERT(MatrixXd dummy(MatrixXd::Random(3,3)));
|
||||
CALL_SUBTEST_1(nomalloc(Matrix<float, 1, 1>()) );
|
||||
@ -207,6 +229,10 @@ void test_nomalloc()
|
||||
|
||||
// Check decomposition modules with dynamic matrices that have a known compile-time max size (ctms)
|
||||
CALL_SUBTEST_4(ctms_decompositions<float>());
|
||||
|
||||
CALL_SUBTEST_5(test_zerosized());
|
||||
|
||||
CALL_SUBTEST_6(test_reference(Matrix<float,32,32>()));
|
||||
CALL_SUBTEST_7(test_reference(R1));
|
||||
CALL_SUBTEST_8(Ref<MatrixXd> R2 = M1.topRows<2>(); test_reference(R2));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user