diff options
-rw-r--r-- | Eigen/src/Core/Array.h | 37 | ||||
-rw-r--r-- | Eigen/src/Core/Matrix.h | 53 | ||||
-rw-r--r-- | Eigen/src/Core/PlainObjectBase.h | 35 | ||||
-rw-r--r-- | test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | test/array.cpp | 2 | ||||
-rw-r--r-- | test/ctorleak.cpp | 36 |
6 files changed, 76 insertions, 88 deletions
diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h index 9a1f30bc8..d8a277143 100644 --- a/Eigen/src/Core/Array.h +++ b/Eigen/src/Core/Array.h @@ -74,7 +74,7 @@ class Array { return Base::operator=(other); } - + /** Set all the entries to \a value. * \sa DenseBase::setConstant(), DenseBase::fill() */ @@ -101,7 +101,7 @@ class Array */ template<typename OtherDerived> EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Array& operator=(const ArrayBase<OtherDerived>& other) + EIGEN_STRONG_INLINE Array& operator=(const DenseBase<OtherDerived>& other) { return Base::_set(other); } @@ -222,43 +222,18 @@ class Array m_storage.data()[3] = val3; } - /** Constructor copying the value of the expression \a other */ - template<typename OtherDerived> - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Array(const ArrayBase<OtherDerived>& other) - : Base(other.rows() * other.cols(), other.rows(), other.cols()) - { - Base::_check_template_params(); - Base::_set_noalias(other); - } /** Copy constructor */ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Array& other) - : Base(other.rows() * other.cols(), other.rows(), other.cols()) - { - Base::_check_template_params(); - Base::_set_noalias(other); - } - /** Copy constructor with in-place evaluation */ - template<typename OtherDerived> - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Array(const ReturnByValue<OtherDerived>& other) - { - Base::_check_template_params(); - Base::resize(other.rows(), other.cols()); - other.evalTo(*this); - } + : Base(other) + { } /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */ template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other) - : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) - { - Base::_check_template_params(); - Base::_resize_to_match(other); - *this = other; - } + : Base(other.derived()) + { } EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; } EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); } diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 88ffd7d60..b4a68e08a 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -25,7 +25,7 @@ namespace Eigen { * * The first three template parameters are required: * \tparam _Scalar \anchor matrix_tparam_scalar Numeric type, e.g. float, double, int or std::complex<float>. - * User defined sclar types are supported as well (see \ref user_defined_scalars "here"). + * User defined scalar types are supported as well (see \ref user_defined_scalars "here"). * \tparam _Rows Number of rows, or \b Dynamic * \tparam _Cols Number of columns, or \b Dynamic * @@ -170,7 +170,7 @@ class Matrix */ template<typename OtherDerived> EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other) + EIGEN_STRONG_INLINE Matrix& operator=(const DenseBase<OtherDerived>& other) { return Base::_set(other); } @@ -266,8 +266,8 @@ class Matrix * * \warning This constructor is disabled for fixed-size \c 1x1 matrices. For instance, * calling Matrix<double,1,1>(1) will call the initialization constructor: Matrix(const Scalar&). - * For fixed-size \c 1x1 matrices it is thefore recommended to use the default - * constructor Matrix() instead, especilly when using one of the non standard + * For fixed-size \c 1x1 matrices it is therefore recommended to use the default + * constructor Matrix() instead, especially when using one of the non standard * \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives). */ EIGEN_STRONG_INLINE explicit Matrix(Index dim); @@ -281,8 +281,8 @@ class Matrix * * \warning This constructor is disabled for fixed-size \c 1x2 and \c 2x1 vectors. For instance, * calling Matrix2f(2,1) will call the initialization constructor: Matrix(const Scalar& x, const Scalar& y). - * For fixed-size \c 1x2 or \c 2x1 vectors it is thefore recommended to use the default - * constructor Matrix() instead, especilly when using one of the non standard + * For fixed-size \c 1x2 or \c 2x1 vectors it is therefore recommended to use the default + * constructor Matrix() instead, especially when using one of the non standard * \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives). */ EIGEN_DEVICE_FUNC @@ -315,37 +315,10 @@ class Matrix } - /** \brief Constructor copying the value of the expression \a other */ - template<typename OtherDerived> - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other) - : Base(other.rows() * other.cols(), other.rows(), other.cols()) - { - // This test resides here, to bring the error messages closer to the user. Normally, these checks - // are performed deeply within the library, thus causing long and scary error traces. - 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) - - Base::_check_template_params(); - Base::_set_noalias(other); - } /** \brief Copy constructor */ EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Matrix(const Matrix& other) - : Base(other.rows() * other.cols(), other.rows(), other.cols()) - { - Base::_check_template_params(); - Base::_set_noalias(other); - } - /** \brief Copy constructor with in-place evaluation */ - template<typename OtherDerived> - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Matrix(const ReturnByValue<OtherDerived>& other) - { - Base::_check_template_params(); - Base::resize(other.rows(), other.cols()); - other.evalTo(*this); - } + EIGEN_STRONG_INLINE Matrix(const Matrix& other) : Base(other) + { } /** \brief Copy constructor for generic expressions. * \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) @@ -353,14 +326,8 @@ class Matrix template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Matrix(const EigenBase<OtherDerived> &other) - : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) - { - Base::_check_template_params(); - Base::_resize_to_match(other); - // FIXME/CHECK: isn't *this = other.derived() more efficient. it allows to - // go for pure _set() implementations, right? - *this = other; - } + : Base(other.derived()) + { } EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; } EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); } diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h index 65d69f484..d331b84ad 100644 --- a/Eigen/src/Core/PlainObjectBase.h +++ b/Eigen/src/Core/PlainObjectBase.h @@ -69,7 +69,7 @@ template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct m #ifdef EIGEN_PARSED_BY_DOXYGEN namespace internal { -// this is a warkaround to doxygen not being able to understand the inheritence logic +// this is a workaround to doxygen not being able to understand the inheritance logic // when it is hidden by the dense_xpr_base helper struct. template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {}; /** This class is just a workaround for Doxygen and it does not not actually exist. */ @@ -479,6 +479,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type } #endif + /** Copy constructor */ + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) + : Base(), m_storage(other.m_storage) { } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols) : m_storage(a_size, nbRows, nbCols) @@ -498,15 +502,36 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type return this->derived(); } - /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */ + /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */ + template<typename OtherDerived> + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other) + : m_storage() + { + _check_template_params(); + resizeLike(other); + _set_noalias(other); + } + + /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */ template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other) - : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + : m_storage() { _check_template_params(); - internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.derived().rows(), other.derived().cols()); - Base::operator=(other.derived()); + resizeLike(other); + *this = other.derived(); + } + /** \brief Copy constructor with in-place evaluation */ + template<typename OtherDerived> + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other) + { + _check_template_params(); + // FIXME this does not automatically transpose vectors if necessary + resize(other.rows(), other.cols()); + other.evalTo(this->derived()); } /** \name Map diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 54ce7fb30..ffd905c27 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -252,6 +252,7 @@ ei_add_test(vectorwiseop) ei_add_test(special_numbers) ei_add_test(rvalue_types) ei_add_test(dense_storage) +ei_add_test(ctorleak) # # ei_add_test(denseLM) diff --git a/test/array.cpp b/test/array.cpp index ad0182e10..cafcf79ab 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -22,6 +22,8 @@ template<typename ArrayType> void array(const ArrayType& m) ArrayType m1 = ArrayType::Random(rows, cols), m2 = ArrayType::Random(rows, cols), m3(rows, cols); + ArrayType m4 = m1; // copy constructor + VERIFY_IS_APPROX(m1, m4); ColVectorType cv1 = ColVectorType::Random(rows); RowVectorType rv1 = RowVectorType::Random(cols); diff --git a/test/ctorleak.cpp b/test/ctorleak.cpp index 145d91be4..c158f5e4e 100644 --- a/test/ctorleak.cpp +++ b/test/ctorleak.cpp @@ -4,48 +4,66 @@ struct Foo { - static unsigned object_count; - static unsigned object_limit; + static Index object_count; + static Index object_limit; int dummy; Foo() { #ifdef EIGEN_EXCEPTIONS // TODO: Is this the correct way to handle this? - if (Foo::object_count > Foo::object_limit) { throw Foo::Fail(); } + if (Foo::object_count > Foo::object_limit) { std::cout << "\nThrow!\n"; throw Foo::Fail(); } #endif + std::cout << '+'; ++Foo::object_count; } ~Foo() { + std::cout << '-'; --Foo::object_count; } class Fail : public std::exception {}; }; -unsigned Foo::object_count = 0; -unsigned Foo::object_limit = 0; +Index Foo::object_count = 0; +Index Foo::object_limit = 0; +#undef EIGEN_TEST_MAX_SIZE +#define EIGEN_TEST_MAX_SIZE 3 void test_ctorleak() { - typedef DenseIndex Index; + typedef Matrix<Foo, Dynamic, Dynamic> MatrixX; + typedef Matrix<Foo, Dynamic, 1> VectorX; Foo::object_count = 0; for(int i = 0; i < g_repeat; i++) { Index rows = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE), cols = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE); - Foo::object_limit = internal::random(0, rows*cols - 2); + Foo::object_limit = internal::random<Index>(0, rows*cols - 2); + std::cout << "object_limit =" << Foo::object_limit << std::endl; #ifdef EIGEN_EXCEPTIONS try { #endif - Matrix<Foo, Dynamic, Dynamic> m(rows, cols); + std::cout << "\nMatrixX m(" << rows << ", " << cols << ");\n"; + MatrixX m(rows, cols); #ifdef EIGEN_EXCEPTIONS VERIFY(false); // not reached if exceptions are enabled } catch (const Foo::Fail&) { /* ignore */ } #endif + VERIFY_IS_EQUAL(Index(0), Foo::object_count); + + { + Foo::object_limit = (rows+1)*(cols+1); + MatrixX A(rows, cols); + VERIFY_IS_EQUAL(Foo::object_count, rows*cols); + VectorX v=A.row(0); + VERIFY_IS_EQUAL(Foo::object_count, (rows+1)*cols); + v = A.col(0); + VERIFY_IS_EQUAL(Foo::object_count, rows*(cols+1)); + } + VERIFY_IS_EQUAL(Index(0), Foo::object_count); } - VERIFY_IS_EQUAL(static_cast<unsigned>(0), Foo::object_count); } |