diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index ac8c8e5ff..5e9271d41 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -1723,14 +1723,14 @@ struct evaluator > EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : m_result(xpr.arg()) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); } // This constructor is used when nesting an EvalTo evaluator in another evaluator EIGEN_DEVICE_FUNC evaluator(const ArgType& arg) : m_result(arg) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); } protected: diff --git a/Eigen/src/Core/Inverse.h b/Eigen/src/Core/Inverse.h index 268f8d4f0..9ab5a7942 100644 --- a/Eigen/src/Core/Inverse.h +++ b/Eigen/src/Core/Inverse.h @@ -104,7 +104,7 @@ struct unary_evaluator > unary_evaluator(const InverseType& inv_xpr) : m_result(inv_xpr.rows(), inv_xpr.cols()) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); internal::call_assignment_no_alias(m_result, inv_xpr); } diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h index a874ee326..4027255a1 100644 --- a/Eigen/src/Core/ProductEvaluators.h +++ b/Eigen/src/Core/ProductEvaluators.h @@ -109,7 +109,7 @@ struct product_evaluator, ProductTag, LhsShape, RhsSh explicit product_evaluator(const XprType& xpr) : m_result(xpr.rows(), xpr.cols()) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); // FIXME shall we handle nested_eval here?, // if so, then we must take care at removing the call to nested_eval in the specializations (e.g., in permutation_matrix_product, transposition_matrix_product, etc.) diff --git a/Eigen/src/Core/Ref.h b/Eigen/src/Core/Ref.h index c31dfccb3..c48650eb4 100644 --- a/Eigen/src/Core/Ref.h +++ b/Eigen/src/Core/Ref.h @@ -199,8 +199,8 @@ protected: return false; } - ::new (static_cast(this)) Base(expr.data(), rows, cols); - ::new (&m_stride) StrideBase( + internal::construct_at(this, expr.data(), rows, cols); + internal::construct_at(&m_stride, (StrideType::OuterStrideAtCompileTime == 0) ? 0 : outer_stride, (StrideType::InnerStrideAtCompileTime == 0) ? 0 : inner_stride ); return true; diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h index d2dd349cb..90252829b 100644 --- a/Eigen/src/Core/ReturnByValue.h +++ b/Eigen/src/Core/ReturnByValue.h @@ -106,7 +106,7 @@ struct evaluator > EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : m_result(xpr.rows(), xpr.cols()) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); xpr.evalTo(m_result); } diff --git a/Eigen/src/Core/Solve.h b/Eigen/src/Core/Solve.h index 3d3a3c946..f77eac917 100644 --- a/Eigen/src/Core/Solve.h +++ b/Eigen/src/Core/Solve.h @@ -125,7 +125,7 @@ struct evaluator > EIGEN_DEVICE_FUNC explicit evaluator(const SolveType& solve) : m_result(solve.rows(), solve.cols()) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); solve.dec()._solve_impl(solve.rhs(), m_result); } diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index 8e724fcaf..8ec1a27bd 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -1150,6 +1150,38 @@ inline int queryTopLevelCacheSize() return (std::max)(l2,l3); } + + +/** \internal + * This wraps C++20's std::construct_at, using placement new instead if it is not available. + */ + +#if EIGEN_COMP_CXXVER >= 20 +using std::construct_at; +#else +template +T* construct_at( T* p, Args&&... args ) +{ + return ::new (const_cast(static_cast(p))) + T(std::forward(args)...); +} +#endif + +/** \internal + * This wraps C++17's std::destroy_at. If it's not available it calls the destructor. + * The wrapper is not a full replacement for C++20's std::destroy_at as it cannot + * be applied to std::array. + */ +#if EIGEN_COMP_CXXVER >= 17 +using std::destroy_at; +#else +template +void destroy_at(T* p) +{ + p->~T(); +} +#endif + } // end namespace internal } // end namespace Eigen diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index d6949f6de..215e5bbe2 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -345,7 +345,7 @@ struct unary_evaluator, IndexBased> EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op) : Base(), m_temp(op) { - ::new (static_cast(this)) Base(m_temp); + internal::construct_at(this, m_temp); } protected: diff --git a/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h index 9e8348a1f..8e294fc42 100644 --- a/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +++ b/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h @@ -79,16 +79,16 @@ public: template void grab(const EigenBase &mat) { - m_matrix.~Ref(); - ::new (&m_matrix) Ref(mat.derived()); + internal::destroy_at(&m_matrix); + internal::construct_at(&m_matrix, mat.derived()); } void grab(const Ref &mat) { if(&(mat.derived()) != &m_matrix) { - m_matrix.~Ref(); - ::new (&m_matrix) Ref(mat); + internal::destroy_at(&m_matrix); + internal::construct_at(&m_matrix, mat); } } diff --git a/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h b/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h index 121363b03..bb56db3cc 100644 --- a/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +++ b/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h @@ -85,7 +85,7 @@ struct evaluator > evaluator(const SolveType& solve) : m_result(solve.rows(), solve.cols()) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); m_result = solve.guess(); solve.dec()._solve_with_guess_impl(solve.rhs(), m_result); } diff --git a/Eigen/src/KLUSupport/KLUSupport.h b/Eigen/src/KLUSupport/KLUSupport.h index 769c45d40..bfe2f669e 100644 --- a/Eigen/src/KLUSupport/KLUSupport.h +++ b/Eigen/src/KLUSupport/KLUSupport.h @@ -265,16 +265,16 @@ class KLU : public SparseSolverBase > template void grab(const EigenBase &A) { - mp_matrix.~KLUMatrixRef(); - ::new (&mp_matrix) KLUMatrixRef(A.derived()); + internal::destroy_at(&mp_matrix); + internal::construct_at(&mp_matrix, A.derived()); } void grab(const KLUMatrixRef &A) { if(&(A.derived()) != &mp_matrix) { - mp_matrix.~KLUMatrixRef(); - ::new (&mp_matrix) KLUMatrixRef(A); + internal::destroy_at(&mp_matrix); + internal::construct_at(&mp_matrix, A); } } diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h index 19b755731..d7dc209f9 100644 --- a/Eigen/src/SVD/JacobiSVD.h +++ b/Eigen/src/SVD/JacobiSVD.h @@ -73,8 +73,8 @@ class qr_preconditioner_impl, ProductTag, Permut explicit product_evaluator(const XprType& xpr) : m_result(xpr.rows(), xpr.cols()) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); generic_product_impl::evalTo(m_result, xpr.lhs(), xpr.rhs()); } diff --git a/Eigen/src/SparseCore/SparseProduct.h b/Eigen/src/SparseCore/SparseProduct.h index de1152951..4ac51746a 100644 --- a/Eigen/src/SparseCore/SparseProduct.h +++ b/Eigen/src/SparseCore/SparseProduct.h @@ -149,7 +149,7 @@ struct unary_evaluator >, IteratorBased> : m_result(xpr.rows(), xpr.cols()) { using std::abs; - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); typedef typename nested_eval::type LhsNested; typedef typename nested_eval::type RhsNested; LhsNested lhsNested(xpr.nestedExpression().lhs()); diff --git a/Eigen/src/SparseCore/SparseRef.h b/Eigen/src/SparseCore/SparseRef.h index 519b72f53..5064908d9 100644 --- a/Eigen/src/SparseCore/SparseRef.h +++ b/Eigen/src/SparseCore/SparseRef.h @@ -100,9 +100,9 @@ protected: void construct(Expression& expr) { if(expr.outerIndexPtr()==0) - ::new (static_cast(this)) Base(expr.size(), expr.nonZeros(), expr.innerIndexPtr(), expr.valuePtr()); + internal::construct_at(this, expr.size(), expr.nonZeros(), expr.innerIndexPtr(), expr.valuePtr()); else - ::new (static_cast(this)) Base(expr.rows(), expr.cols(), expr.nonZeros(), expr.outerIndexPtr(), expr.innerIndexPtr(), expr.valuePtr(), expr.innerNonZeroPtr()); + internal::construct_at(this, expr.rows(), expr.cols(), expr.nonZeros(), expr.outerIndexPtr(), expr.innerIndexPtr(), expr.valuePtr(), expr.innerNonZeroPtr()); } }; @@ -203,8 +203,7 @@ class Ref, Options, StrideType ~Ref() { if(m_hasCopy) { - TPlainObjectType* obj = reinterpret_cast(&m_storage); - obj->~TPlainObjectType(); + internal::destroy_at(reinterpret_cast(&m_storage)); } } @@ -215,8 +214,7 @@ class Ref, Options, StrideType { if((Options & int(StandardCompressedFormat)) && (!expr.isCompressed())) { - TPlainObjectType* obj = reinterpret_cast(&m_storage); - ::new (obj) TPlainObjectType(expr); + TPlainObjectType* obj = internal::construct_at(reinterpret_cast(&m_storage), expr); m_hasCopy = true; Base::construct(*obj); } @@ -229,8 +227,7 @@ class Ref, Options, StrideType template void construct(const Expression& expr, internal::false_type) { - TPlainObjectType* obj = reinterpret_cast(&m_storage); - ::new (obj) TPlainObjectType(expr); + TPlainObjectType* obj = internal::construct_at(reinterpret_cast(&m_storage), expr); m_hasCopy = true; Base::construct(*obj); } @@ -321,8 +318,7 @@ class Ref, Options, StrideType ~Ref() { if(m_hasCopy) { - TPlainObjectType* obj = reinterpret_cast(&m_storage); - obj->~TPlainObjectType(); + internal::destroy_at(reinterpret_cast(&m_storage)); } } @@ -337,8 +333,7 @@ class Ref, Options, StrideType template void construct(const Expression& expr, internal::false_type) { - TPlainObjectType* obj = reinterpret_cast(&m_storage); - ::new (obj) TPlainObjectType(expr); + TPlainObjectType* obj = internal::construct_at(reinterpret_cast(&m_storage), expr); m_hasCopy = true; Base::construct(*obj); } diff --git a/Eigen/src/SparseCore/SparseSelfAdjointView.h b/Eigen/src/SparseCore/SparseSelfAdjointView.h index 06f2571b2..a4bbc88a1 100644 --- a/Eigen/src/SparseCore/SparseSelfAdjointView.h +++ b/Eigen/src/SparseCore/SparseSelfAdjointView.h @@ -383,7 +383,7 @@ struct product_evaluator, ProductTag, Spar product_evaluator(const XprType& xpr) : m_lhs(xpr.lhs()), m_result(xpr.rows(), xpr.cols()) { - ::new (static_cast(this)) Base(m_result); + internal::construct_at(this, m_result); generic_product_impl::evalTo(m_result, m_lhs, xpr.rhs()); } diff --git a/Eigen/src/UmfPackSupport/UmfPackSupport.h b/Eigen/src/UmfPackSupport/UmfPackSupport.h index 10a8ae265..d9a8d38c4 100644 --- a/Eigen/src/UmfPackSupport/UmfPackSupport.h +++ b/Eigen/src/UmfPackSupport/UmfPackSupport.h @@ -531,16 +531,16 @@ class UmfPackLU : public SparseSolverBase > template void grab(const EigenBase &A) { - mp_matrix.~UmfpackMatrixRef(); - ::new (&mp_matrix) UmfpackMatrixRef(A.derived()); + internal::destroy_at(&mp_matrix); + internal::construct_at(&mp_matrix, A.derived()); } void grab(const UmfpackMatrixRef &A) { if(&(A.derived()) != &mp_matrix) { - mp_matrix.~UmfpackMatrixRef(); - ::new (&mp_matrix) UmfpackMatrixRef(A); + internal::destroy_at(&mp_matrix); + internal::construct_at(&mp_matrix, A); } }