diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h index b65285282..1242d1946 100644 --- a/Eigen/src/Core/Array.h +++ b/Eigen/src/Core/Array.h @@ -21,6 +21,10 @@ struct traits > : tra typedef ArrayXpr XprKind; typedef ArrayBase > XprBase; }; + +template +struct has_trivially_copyable_storage > + : has_trivially_copyable_storage > {}; } /** \class Array @@ -120,6 +124,12 @@ class Array return Base::_set(other); } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE Array& operator=( + const Array& other) requires internal::has_trivially_copyable_storage::value = default; +#endif + /** Default constructor. * * For fixed-size matrices, does nothing. @@ -159,6 +169,13 @@ class Array return *this; } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC Array(Array&& other) EIGEN_NOEXCEPT + requires internal::has_trivially_copyable_storage::value = default; + EIGEN_DEVICE_FUNC Array& operator=(Array&& other) EIGEN_NOEXCEPT + requires internal::has_trivially_copyable_storage::value = default; +#endif + /** \copydoc PlainObjectBase(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) * * Example: \include Array_variadic_ctor_cxx11.cpp @@ -266,6 +283,12 @@ class Array : Base(other) { } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE Array(const Array& other) requires internal::has_trivially_copyable_storage::value = + default; +#endif + private: struct PrivateType {}; public: diff --git a/Eigen/src/Core/ArrayBase.h b/Eigen/src/Core/ArrayBase.h index 28397e5cf..2d6fe4250 100644 --- a/Eigen/src/Core/ArrayBase.h +++ b/Eigen/src/Core/ArrayBase.h @@ -112,6 +112,11 @@ template class ArrayBase return derived(); } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ArrayBase& operator=( + const ArrayBase& other) requires internal::has_trivially_copyable_storage::value = default; +#endif + /** Set all the entries to \a value. * \sa DenseBase::setConstant(), DenseBase::fill() */ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index d62c851de..6d5a10022 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -275,6 +275,11 @@ template class DenseBase EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const DenseBase& other); +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseBase& operator=( + const DenseBase& other) requires internal::has_trivially_copyable_storage::value = default; +#endif + template EIGEN_DEVICE_FUNC Derived& operator=(const EigenBase &other); diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 44c0e258f..77051a0b7 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -52,6 +52,14 @@ public: Alignment = actual_alignment }; }; + +template +struct has_trivially_copyable_storage > +{ + // Must be identical to the type of PlainObjectBase::m_storage. + typedef DenseStorage::ret, Rows_, Cols_, Options_> Storage; + static const bool value = std::is_trivially_copyable::value; +}; } /** \class Matrix @@ -210,6 +218,12 @@ class Matrix return Base::_set(other); } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE Matrix& operator=( + const Matrix& other) requires internal::has_trivially_copyable_storage::value = default; +#endif + /** \internal * \brief Copies the value of the expression \a other into \c *this with automatic resizing. * @@ -279,6 +293,13 @@ class Matrix return *this; } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Matrix(Matrix&& other) EIGEN_NOEXCEPT + requires internal::has_trivially_copyable_storage::value = default; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT + requires internal::has_trivially_copyable_storage::value = default; +#endif + /** \copydoc PlainObjectBase(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&... args) * * Example: \include Matrix_variadic_ctor_cxx11.cpp @@ -404,6 +425,12 @@ class Matrix EIGEN_STRONG_INLINE Matrix(const Matrix& other) : Base(other) { } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE Matrix(const Matrix& other) requires internal::has_trivially_copyable_storage::value = + default; +#endif + /** \brief Copy constructor for generic expressions. * \sa MatrixBase::operator=(const EigenBase&) */ diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 70d0cf77f..89a411010 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -140,6 +140,11 @@ template class MatrixBase EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const MatrixBase& other); +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE MatrixBase& operator=( + const MatrixBase& other) requires internal::has_trivially_copyable_storage::value = default; +#endif + // We cannot inherit here via Base::operator= since it is causing // trouble with MSVC. diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h index 4367ea5c0..33ae5072d 100644 --- a/Eigen/src/Core/PlainObjectBase.h +++ b/Eigen/src/Core/PlainObjectBase.h @@ -463,6 +463,12 @@ class PlainObjectBase : public internal::dense_xpr_base::type return _set(other); } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE PlainObjectBase& operator=( + const PlainObjectBase& other) requires internal::has_trivially_copyable_storage::value = default; +#endif + /** \sa MatrixBase::lazyAssign() */ template EIGEN_DEVICE_FUNC @@ -514,10 +520,27 @@ class PlainObjectBase : public internal::dense_xpr_base::type return *this; } +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC + PlainObjectBase(PlainObjectBase&& other) EIGEN_NOEXCEPT + requires internal::has_trivially_copyable_storage::value = default; + + EIGEN_DEVICE_FUNC + PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT + requires internal::has_trivially_copyable_storage::value = default; +#endif + /** Copy constructor */ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) : Base(), m_storage(other.m_storage) { } + +#if EIGEN_COMP_HAS_P0848R3 + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE PlainObjectBase( + const PlainObjectBase& other) requires internal::has_trivially_copyable_storage::value = default; +#endif + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols) : m_storage(size, rows, cols) diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index cb12c77e3..f745914b2 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -42,6 +42,11 @@ template struct evaluator_traits; template< typename T> struct evaluator; +template struct has_trivially_copyable_storage +{ + static const bool value = false; +}; + } // end namespace internal template struct NumTraits; diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index bb1fe5b01..32bb16805 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -1084,6 +1084,16 @@ namespace Eigen { } #endif +/** + * \internal + * \brief Macro for conditionally trivial special member functions for supporting trivially copyable types. + * This feature is officially known as C++20's P0848R3 and is enabled on supported compilers. + */ +#if (EIGEN_COMP_CXXVER >= 20) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_MSVC_STRICT) +#define EIGEN_COMP_HAS_P0848R3 1 +#else +#define EIGEN_COMP_HAS_P0848R3 0 +#endif /** * \internal diff --git a/test/dense_storage.cpp b/test/dense_storage.cpp index 398cb3266..370900014 100644 --- a/test/dense_storage.cpp +++ b/test/dense_storage.cpp @@ -20,6 +20,11 @@ static_assert(std::is_trivially_move_assignable::value, "Dense static_assert(std::is_trivially_copy_constructible::value, "DenseStorage not trivially_copy_constructible"); static_assert(std::is_trivially_copy_assignable::value, "DenseStorage not trivially_copy_assignable"); static_assert(std::is_trivially_copyable::value, "DenseStorage not trivially_copyable"); +#if EIGEN_COMP_HAS_P0848R3 +static_assert(std::is_trivially_copyable::value, "Eigen::Matrix3d not trivially_copyable"); +static_assert(std::is_trivially_copyable::value, "Eigen::Array33d not trivially_copyable"); +static_assert(!std::is_trivially_copyable>::value, "Eigen::Matrix3 is trivially_copyable"); +#endif #endif template diff --git a/unsupported/Eigen/CXX11/Tensor b/unsupported/Eigen/CXX11/Tensor index 0a04a0e0c..25f1fb957 100644 --- a/unsupported/Eigen/CXX11/Tensor +++ b/unsupported/Eigen/CXX11/Tensor @@ -39,6 +39,16 @@ #include #include #include + +// C++20 libstdc++'s headers have non-parenthesized calls to max() and min(). +#if EIGEN_COMP_HAS_P0848R3 +#ifdef max +#undef max +#endif +#ifdef min +#undef min +#endif +#endif #include #if defined(EIGEN_USE_THREADS) || defined(EIGEN_USE_SYCL) diff --git a/unsupported/Eigen/CXX11/ThreadPool b/unsupported/Eigen/CXX11/ThreadPool index 6ebe9e779..4f9600236 100644 --- a/unsupported/Eigen/CXX11/ThreadPool +++ b/unsupported/Eigen/CXX11/ThreadPool @@ -39,9 +39,7 @@ #include #include #include -#include #include -#include #include // There are non-parenthesized calls to "max" in the header, @@ -53,6 +51,15 @@ #endif #include +// C++20 libstdc++'s headers also calls "max" and "min" indirectly. +#if EIGEN_COMP_HAS_P0848R3 +#ifdef min +#undef min +#endif +#endif +#include +#include + #include "src/util/CXX11Meta.h" #include "src/util/MaxSizeVector.h"