mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Add construct_at, destroy_at wrappers. Use throughout.
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
dfa5176780
commit
cd2ba9d03e
@@ -1723,14 +1723,14 @@ struct evaluator<EvalToTemp<ArgType> >
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
|
||||
: m_result(xpr.arg())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
internal::construct_at<Base>(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<Base*>(this)) Base(m_result);
|
||||
internal::construct_at<Base>(this, m_result);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -104,7 +104,7 @@ struct unary_evaluator<Inverse<ArgType> >
|
||||
unary_evaluator(const InverseType& inv_xpr)
|
||||
: m_result(inv_xpr.rows(), inv_xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
internal::construct_at<Base>(this, m_result);
|
||||
internal::call_assignment_no_alias(m_result, inv_xpr);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ struct product_evaluator<Product<Lhs, Rhs, Options>, ProductTag, LhsShape, RhsSh
|
||||
explicit product_evaluator(const XprType& xpr)
|
||||
: m_result(xpr.rows(), xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
internal::construct_at<Base>(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.)
|
||||
|
||||
@@ -199,8 +199,8 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
::new (static_cast<Base*>(this)) Base(expr.data(), rows, cols);
|
||||
::new (&m_stride) StrideBase(
|
||||
internal::construct_at<Base>(this, expr.data(), rows, cols);
|
||||
internal::construct_at(&m_stride,
|
||||
(StrideType::OuterStrideAtCompileTime == 0) ? 0 : outer_stride,
|
||||
(StrideType::InnerStrideAtCompileTime == 0) ? 0 : inner_stride );
|
||||
return true;
|
||||
|
||||
@@ -106,7 +106,7 @@ struct evaluator<ReturnByValue<Derived> >
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
|
||||
: m_result(xpr.rows(), xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
internal::construct_at<Base>(this, m_result);
|
||||
xpr.evalTo(m_result);
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ struct evaluator<Solve<Decomposition,RhsType> >
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const SolveType& solve)
|
||||
: m_result(solve.rows(), solve.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
internal::construct_at<Base>(this, m_result);
|
||||
solve.dec()._solve_impl(solve.rhs(), m_result);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<class T, class... Args>
|
||||
T* construct_at( T* p, Args&&... args )
|
||||
{
|
||||
return ::new (const_cast<void*>(static_cast<const volatile void*>(p)))
|
||||
T(std::forward<Args>(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<class T>
|
||||
void destroy_at(T* p)
|
||||
{
|
||||
p->~T();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
Reference in New Issue
Block a user