diff options
author | Gael Guennebaud <g.gael@free.fr> | 2018-07-18 23:33:07 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2018-07-18 23:33:07 +0200 |
commit | 863580fe881c32af82eb106817e71dc560d9e775 (patch) | |
tree | 44a1b4d4ee9d5d816ca1006e620e865cba7b08d4 /Eigen/src/Core/PlainObjectBase.h | |
parent | 053ed97c72543d513e92cdef1b14839844664c34 (diff) |
bug #1432: fix conservativeResize for non-relocatable scalar types. For those we need to by-pass realloc routines and fall-back to allocate as new - copy - delete. The remaining problem is that we don't have any mechanism to accurately determine whether a type is relocatable or not, so currently let's be super conservative using either RequireInitialization or std::is_trivially_copyable
Diffstat (limited to 'Eigen/src/Core/PlainObjectBase.h')
-rw-r--r-- | Eigen/src/Core/PlainObjectBase.h | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h index 6c0a42ec7..016e76a53 100644 --- a/Eigen/src/Core/PlainObjectBase.h +++ b/Eigen/src/Core/PlainObjectBase.h @@ -921,13 +921,19 @@ namespace internal { template <typename Derived, typename OtherDerived, bool IsVector> struct conservative_resize_like_impl { + #if EIGEN_HAS_TYPE_TRAITS + static const bool IsRelocatable = std::is_trivially_copyable<typename Derived::Scalar>::value; + #else + static const bool IsRelocatable = NumTraits<typename Derived::Scalar>::RequireInitialization; + #endif static void run(DenseBase<Derived>& _this, Index rows, Index cols) { if (_this.rows() == rows && _this.cols() == cols) return; EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) - if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows - (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns + if ( IsRelocatable + && (( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows + (!Derived::IsRowMajor && _this.rows() == rows) )) // column-major and we change only the number of columns { internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols); _this.derived().m_storage.conservativeResize(rows*cols,rows,cols); @@ -955,8 +961,9 @@ struct conservative_resize_like_impl EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) - if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows - (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns + if ( IsRelocatable && + (( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows + (!Derived::IsRowMajor && _this.rows() == other.rows()) )) // column-major and we change only the number of columns { const Index new_rows = other.rows() - _this.rows(); const Index new_cols = other.cols() - _this.cols(); @@ -984,13 +991,18 @@ template <typename Derived, typename OtherDerived> struct conservative_resize_like_impl<Derived,OtherDerived,true> : conservative_resize_like_impl<Derived,OtherDerived,false> { - using conservative_resize_like_impl<Derived,OtherDerived,false>::run; + typedef conservative_resize_like_impl<Derived,OtherDerived,false> Base; + using Base::run; + using Base::IsRelocatable; static void run(DenseBase<Derived>& _this, Index size) { const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size; const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1; - _this.derived().m_storage.conservativeResize(size,new_rows,new_cols); + if(IsRelocatable) + _this.derived().m_storage.conservativeResize(size,new_rows,new_cols); + else + Base::run(_this.derived(), new_rows, new_cols); } static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) @@ -1001,7 +1013,10 @@ struct conservative_resize_like_impl<Derived,OtherDerived,true> const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows(); const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1; - _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols); + if(IsRelocatable) + _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols); + else + Base::run(_this.derived(), new_rows, new_cols); if (num_new_elements > 0) _this.tail(num_new_elements) = other.tail(num_new_elements); |