diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h index 7be8971ba..d7a5e7aef 100644 --- a/Eigen/src/Core/Array.h +++ b/Eigen/src/Core/Array.h @@ -193,8 +193,9 @@ class Array * * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */ - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Array(const std::initializer_list>& list) : Base(list) {} + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Array( + const std::initializer_list>& list) + : Base(list) {} #ifndef EIGEN_PARSED_BY_DOXYGEN template diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index 24dc69703..bcfd0f611 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -670,8 +670,7 @@ template class DenseBase protected: EIGEN_DEFAULT_COPY_CONSTRUCTOR(DenseBase) /** Default constructor. Do nothing. */ - EIGEN_DEVICE_FUNC DenseBase() - { + EIGEN_DEVICE_FUNC constexpr DenseBase() { /* Just checks for self-consistency of the flags. * Only do it when debugging Eigen, as this borders on paranoia and could slow compilation down */ diff --git a/Eigen/src/Core/DenseStorage.h b/Eigen/src/Core/DenseStorage.h index 4f8a2b65e..cf588bd58 100644 --- a/Eigen/src/Core/DenseStorage.h +++ b/Eigen/src/Core/DenseStorage.h @@ -26,14 +26,12 @@ namespace internal { struct constructor_without_unaligned_array_assert {}; -template -EIGEN_DEVICE_FUNC -void check_static_allocation_size() -{ - // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit - #if EIGEN_STACK_ALLOCATION_LIMIT +template +EIGEN_DEVICE_FUNC constexpr void check_static_allocation_size() { +// if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit +#if EIGEN_STACK_ALLOCATION_LIMIT EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); - #endif +#endif } /** \internal @@ -47,16 +45,10 @@ struct plain_array { T array[Size]; - EIGEN_DEVICE_FUNC - plain_array() - { - check_static_allocation_size(); - } + EIGEN_DEVICE_FUNC constexpr plain_array() { check_static_allocation_size(); } - EIGEN_DEVICE_FUNC - plain_array(constructor_without_unaligned_array_assert) - { - check_static_allocation_size(); + EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) { + check_static_allocation_size(); } }; @@ -87,17 +79,13 @@ struct plain_array { EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size]; - EIGEN_DEVICE_FUNC - plain_array() - { + EIGEN_DEVICE_FUNC constexpr plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7); check_static_allocation_size(); } - EIGEN_DEVICE_FUNC - plain_array(constructor_without_unaligned_array_assert) - { - check_static_allocation_size(); + EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) { + check_static_allocation_size(); } }; @@ -106,17 +94,13 @@ struct plain_array { EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size]; - EIGEN_DEVICE_FUNC - plain_array() - { + EIGEN_DEVICE_FUNC constexpr plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15); check_static_allocation_size(); } - EIGEN_DEVICE_FUNC - plain_array(constructor_without_unaligned_array_assert) - { - check_static_allocation_size(); + EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) { + check_static_allocation_size(); } }; @@ -125,17 +109,13 @@ struct plain_array { EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size]; - EIGEN_DEVICE_FUNC - plain_array() - { + EIGEN_DEVICE_FUNC constexpr plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31); check_static_allocation_size(); } - EIGEN_DEVICE_FUNC - plain_array(constructor_without_unaligned_array_assert) - { - check_static_allocation_size(); + EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) { + check_static_allocation_size(); } }; @@ -144,17 +124,13 @@ struct plain_array { EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size]; - EIGEN_DEVICE_FUNC - plain_array() - { + EIGEN_DEVICE_FUNC constexpr plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63); check_static_allocation_size(); } - EIGEN_DEVICE_FUNC - plain_array(constructor_without_unaligned_array_assert) - { - check_static_allocation_size(); + EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) { + check_static_allocation_size(); } }; @@ -162,8 +138,8 @@ template struct plain_array { T array[1]; - EIGEN_DEVICE_FUNC plain_array() {} - EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {} + EIGEN_DEVICE_FUNC constexpr plain_array() {} + EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {} }; struct plain_array_helper { @@ -211,26 +187,25 @@ template class DenseSt { internal::plain_array m_data; public: - EIGEN_DEVICE_FUNC DenseStorage() { + constexpr EIGEN_DEVICE_FUNC DenseStorage() { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size) } - EIGEN_DEVICE_FUNC - explicit DenseStorage(internal::constructor_without_unaligned_array_assert) + EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()) {} #if defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN) - EIGEN_DEVICE_FUNC + EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other) : m_data(other.m_data) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size) } #else - EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) = default; + EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage&) = default; #endif - EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) = default; - EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&&) = default; - EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&&) = default; - EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) { + EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(const DenseStorage&) = default; + EIGEN_DEVICE_FUNC constexpr DenseStorage(DenseStorage&&) = default; + EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(DenseStorage&&) = default; + EIGEN_DEVICE_FUNC constexpr DenseStorage(Index size, Index rows, Index cols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) - eigen_internal_assert(size==rows*cols && rows==Rows_ && cols==Cols_); + eigen_internal_assert(size == rows * cols && rows == Rows_ && cols == Cols_); EIGEN_UNUSED_VARIABLE(size); EIGEN_UNUSED_VARIABLE(rows); EIGEN_UNUSED_VARIABLE(cols); @@ -238,12 +213,12 @@ template class DenseSt EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { numext::swap(m_data, other.m_data); } - EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;} - EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return Cols_;} - EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {} - EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {} - EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; } - EIGEN_DEVICE_FUNC T *data() { return m_data.array; } + EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT { return Rows_; } + EIGEN_DEVICE_FUNC static constexpr Index cols(void) EIGEN_NOEXCEPT { return Cols_; } + EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index, Index) {} + EIGEN_DEVICE_FUNC constexpr void resize(Index, Index, Index) {} + EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; } + EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; } }; // null matrix @@ -252,18 +227,18 @@ class DenseStorage { public: static_assert(Rows_ * Cols_ == 0, "The fixed number of rows times columns must equal the storage size."); - EIGEN_DEVICE_FUNC DenseStorage() {} - EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) {} - EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) {} - EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; } - EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {} - EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {} - EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;} - EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return Cols_;} - EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {} - EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {} - EIGEN_DEVICE_FUNC const T *data() const { return 0; } - EIGEN_DEVICE_FUNC T *data() { return 0; } + EIGEN_DEVICE_FUNC constexpr DenseStorage() {} + EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) {} + EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage&) {} + EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(const DenseStorage&) { return *this; } + EIGEN_DEVICE_FUNC constexpr DenseStorage(Index,Index,Index) {} + EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage& ) {} + EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT {return Rows_;} + EIGEN_DEVICE_FUNC static constexpr Index cols(void) EIGEN_NOEXCEPT {return Cols_;} + EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index,Index,Index) {} + EIGEN_DEVICE_FUNC constexpr void resize(Index,Index,Index) {} + EIGEN_DEVICE_FUNC constexpr const T *data() const { return 0; } + EIGEN_DEVICE_FUNC constexpr T *data() { return 0; } }; // more specializations for null matrices; these are necessary to resolve ambiguities @@ -373,14 +348,13 @@ class DenseStorage Index m_rows; Index m_cols; public: - EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {} - EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) - : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {} - EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) - : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows), m_cols(other.m_cols) - { - internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data); - } + EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(), m_rows(0), m_cols(0) {} + EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {} + EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other) + : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows), m_cols(other.m_cols) { + internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data); + } EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) { if (this != &other) @@ -391,19 +365,25 @@ class DenseStorage } return *this; } - EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {} + EIGEN_DEVICE_FUNC constexpr DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {} EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { internal::plain_array_helper::swap(m_data, m_rows * m_cols, other.m_data, other.m_rows * other.m_cols); numext::swap(m_rows,other.m_rows); numext::swap(m_cols,other.m_cols); } - EIGEN_DEVICE_FUNC Index rows() const {return m_rows;} - EIGEN_DEVICE_FUNC Index cols() const {return m_cols;} - EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; } - EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; } - EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; } - EIGEN_DEVICE_FUNC T *data() { return m_data.array; } + EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; } + EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; } + EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index rows, Index cols) { + m_rows = rows; + m_cols = cols; + } + EIGEN_DEVICE_FUNC constexpr void resize(Index, Index rows, Index cols) { + m_rows = rows; + m_cols = cols; + } + EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; } + EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; } }; // dynamic-size matrix with fixed-size storage and fixed width @@ -413,15 +393,14 @@ class DenseStorage internal::plain_array m_data; Index m_rows; public: - EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {} - EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) - : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} - EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) - : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows) - { + EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_rows(0) {} + EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} + EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other) + : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows) { internal::plain_array_helper::copy(other.m_data, m_rows * Cols_, m_data); - } - + } + EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) { if (this != &other) @@ -431,18 +410,18 @@ class DenseStorage } return *this; } - EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {} + EIGEN_DEVICE_FUNC constexpr DenseStorage(Index, Index rows, Index) : m_rows(rows) {} EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { internal::plain_array_helper::swap(m_data, m_rows * Cols_, other.m_data, other.m_rows * Cols_); numext::swap(m_rows, other.m_rows); } - EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;} - EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols(void) const EIGEN_NOEXCEPT {return Cols_;} - EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; } - EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; } - EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; } - EIGEN_DEVICE_FUNC T *data() { return m_data.array; } + EIGEN_DEVICE_FUNC constexpr Index rows(void) const EIGEN_NOEXCEPT { return m_rows; } + EIGEN_DEVICE_FUNC constexpr Index cols(void) const EIGEN_NOEXCEPT { return Cols_; } + EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index rows, Index) { m_rows = rows; } + EIGEN_DEVICE_FUNC constexpr void resize(Index, Index rows, Index) { m_rows = rows; } + EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; } + EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; } }; // dynamic-size matrix with fixed-size storage and fixed height @@ -452,14 +431,13 @@ class DenseStorage internal::plain_array m_data; Index m_cols; public: - EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {} - EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) - : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} - EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) - : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(other.m_cols) - { + EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_cols(0) {} + EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) + : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} + EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other) + : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(other.m_cols) { internal::plain_array_helper::copy(other.m_data, Rows_ * m_cols, m_data); - } + } EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) { if (this != &other) @@ -474,12 +452,12 @@ class DenseStorage internal::plain_array_helper::swap(m_data, Rows_ * m_cols, other.m_data, Rows_ * other.m_cols); numext::swap(m_cols, other.m_cols); } - EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows(void) const EIGEN_NOEXCEPT {return Rows_;} - EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;} - EIGEN_DEVICE_FUNC void conservativeResize(Index, Index, Index cols) { m_cols = cols; } - EIGEN_DEVICE_FUNC void resize(Index, Index, Index cols) { m_cols = cols; } - EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; } - EIGEN_DEVICE_FUNC T *data() { return m_data.array; } + EIGEN_DEVICE_FUNC constexpr Index rows(void) const EIGEN_NOEXCEPT { return Rows_; } + EIGEN_DEVICE_FUNC constexpr Index cols(void) const EIGEN_NOEXCEPT { return m_cols; } + EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index, Index cols) { m_cols = cols; } + EIGEN_DEVICE_FUNC constexpr void resize(Index, Index, Index cols) { m_cols = cols; } + EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; } + EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; } }; // purely dynamic matrix. @@ -490,15 +468,16 @@ class DenseStorage Index m_rows; Index m_cols; public: - EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0), m_cols(0) {} - EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) + EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_rows(0), m_cols(0) {} + EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0), m_cols(0) {} - EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) - : m_data(internal::conditional_aligned_new_auto(size)), m_rows(rows), m_cols(cols) - { + EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) + : m_data(internal::conditional_aligned_new_auto(size)), + m_rows(rows), + m_cols(cols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0); - } + } EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(internal::conditional_aligned_new_auto(other.m_rows*other.m_cols)) , m_rows(other.m_rows) @@ -573,14 +552,14 @@ class DenseStorage { T *m_data; Index m_cols; public: - EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_cols(0) {} - explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} - EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto(size)), m_cols(cols) - { + EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_cols(0) {} + explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} + EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) + : m_data(internal::conditional_aligned_new_auto(size)), m_cols(cols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) eigen_internal_assert(size==rows*cols && rows==Rows_ && cols >=0); EIGEN_UNUSED_VARIABLE(rows); - } + } EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(internal::conditional_aligned_new_auto(Rows_*other.m_cols)) , m_cols(other.m_cols) @@ -617,7 +596,7 @@ class DenseStorage { numext::swap(m_data,other.m_data); numext::swap(m_cols,other.m_cols); } - EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;} + EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT { return Rows_; } EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;} EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols) { @@ -648,14 +627,14 @@ class DenseStorage T *m_data; Index m_rows; public: - EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0) {} - explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} - EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto(size)), m_rows(rows) - { + EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_rows(0) {} + explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} + EIGEN_DEVICE_FUNC constexpr DenseStorage(Index size, Index rows, Index cols) + : m_data(internal::conditional_aligned_new_auto(size)), m_rows(rows) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) eigen_internal_assert(size==rows*cols && rows>=0 && cols == Cols_); EIGEN_UNUSED_VARIABLE(cols); - } + } EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(internal::conditional_aligned_new_auto(other.m_rows*Cols_)) , m_rows(other.m_rows) @@ -693,7 +672,7 @@ class DenseStorage numext::swap(m_rows,other.m_rows); } EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;} - EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) {return Cols_;} + EIGEN_DEVICE_FUNC static constexpr Index cols(void) { return Cols_; } void conservativeResize(Index size, Index rows, Index) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*Cols_); diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 23acd8ae7..c7747f16d 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -312,8 +312,9 @@ class Matrix * * \sa Matrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */ - EIGEN_DEVICE_FUNC - explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list>& list) : Base(list) {} + EIGEN_DEVICE_FUNC explicit constexpr EIGEN_STRONG_INLINE Matrix( + const std::initializer_list>& list) + : Base(list) {} #ifndef EIGEN_PARSED_BY_DOXYGEN diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h index 222eaf5f6..60a75b1d6 100644 --- a/Eigen/src/Core/PlainObjectBase.h +++ b/Eigen/src/Core/PlainObjectBase.h @@ -29,18 +29,13 @@ namespace Eigen { namespace internal { template struct check_rows_cols_for_overflow { - template - EIGEN_DEVICE_FUNC - static EIGEN_ALWAYS_INLINE void run(Index, Index) - { - } + template + EIGEN_DEVICE_FUNC static EIGEN_ALWAYS_INLINE constexpr void run(Index, Index) {} }; template<> struct check_rows_cols_for_overflow { - template - EIGEN_DEVICE_FUNC - static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols) - { + template + EIGEN_DEVICE_FUNC static EIGEN_ALWAYS_INLINE constexpr void run(Index rows, Index cols) { // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 // we assume Index is signed Index max_index = (std::size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed @@ -160,12 +155,10 @@ class PlainObjectBase : public internal::dense_xpr_base::type * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts. * * See DenseCoeffsBase::coeff(Index) const for details. */ - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const - { - if(Flags & RowMajorBit) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const Scalar& coeff(Index rowId, Index colId) const { + if (Flags & RowMajorBit) return m_storage.data()[colId + rowId * m_storage.cols()]; - else // column-major + else // column-major return m_storage.data()[rowId + colId * m_storage.rows()]; } @@ -183,12 +176,10 @@ class PlainObjectBase : public internal::dense_xpr_base::type * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts. * * See DenseCoeffsBase::coeffRef(Index,Index) const for details. */ - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId) - { - if(Flags & RowMajorBit) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& coeffRef(Index rowId, Index colId) { + if (Flags & RowMajorBit) return m_storage.data()[colId + rowId * m_storage.cols()]; - else // column-major + else // column-major return m_storage.data()[rowId + colId * m_storage.rows()]; } @@ -196,28 +187,20 @@ class PlainObjectBase : public internal::dense_xpr_base::type * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts. * * See DenseCoeffsBase::coeffRef(Index) const for details. */ - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) - { - return m_storage.data()[index]; - } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& coeffRef(Index index) { return m_storage.data()[index]; } /** This is the const version of coeffRef(Index,Index) which is thus synonym of coeff(Index,Index). * It is provided for convenience. */ - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const - { - if(Flags & RowMajorBit) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const Scalar& coeffRef(Index rowId, Index colId) const { + if (Flags & RowMajorBit) return m_storage.data()[colId + rowId * m_storage.cols()]; - else // column-major + else // column-major return m_storage.data()[rowId + colId * m_storage.rows()]; } /** This is the const version of coeffRef(Index) which is thus synonym of coeff(Index). * It is provided for convenience. */ - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const - { + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const Scalar& coeffRef(Index index) const { return m_storage.data()[index]; } @@ -279,9 +262,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t) */ - EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE void resize(Index rows, Index cols) - { + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index rows, Index cols) { eigen_assert(internal::check_implication(RowsAtCompileTime!=Dynamic, rows==RowsAtCompileTime) && internal::check_implication(ColsAtCompileTime!=Dynamic, cols==ColsAtCompileTime) && internal::check_implication(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic, rows<=MaxRowsAtCompileTime) @@ -309,12 +290,13 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t) */ - EIGEN_DEVICE_FUNC - inline void resize(Index size) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) - eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0); - #ifdef EIGEN_INITIALIZE_COEFFS + EIGEN_DEVICE_FUNC inline constexpr void resize(Index size) { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) + eigen_assert( + ((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime == Dynamic || size <= MaxSizeAtCompileTime)) || + SizeAtCompileTime == size) && + size >= 0); +#ifdef EIGEN_INITIALIZE_COEFFS bool size_changed = size != this->size(); #endif if(RowsAtCompileTime == 1) @@ -334,11 +316,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * \sa resize(Index,Index) */ - EIGEN_DEVICE_FUNC - inline void resize(NoChange_t, Index cols) - { - resize(rows(), cols); - } + EIGEN_DEVICE_FUNC inline constexpr void resize(NoChange_t, Index cols) { resize(rows(), cols); } /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange * as in the example below. @@ -348,11 +326,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * \sa resize(Index,Index) */ - EIGEN_DEVICE_FUNC - inline void resize(Index rows, NoChange_t) - { - resize(rows, cols()); - } + EIGEN_DEVICE_FUNC inline constexpr void resize(Index rows, NoChange_t) { resize(rows, cols()); } /** Resizes \c *this to have the same dimensions as \a other. * Takes care of doing all the checking that's needed. @@ -552,10 +526,9 @@ class PlainObjectBase : public internal::dense_xpr_base::type /** \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer * lists */ - EIGEN_DEVICE_FUNC - explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list>& list) - : m_storage() - { + EIGEN_DEVICE_FUNC explicit constexpr EIGEN_STRONG_INLINE PlainObjectBase( + const std::initializer_list>& list) + : m_storage() { size_t list_size = 0; if (list.begin() != list.end()) { list_size = list.begin()->size(); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8ffa0024f..fb7165c5d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -185,6 +185,18 @@ ei_add_test(io) ei_add_test(packetmath "-DEIGEN_FAST_MATH=1") ei_add_test(vectorization_logic) ei_add_test(basicstuff) +ei_add_test_internal(constexpr constexpr_cxx14) +target_compile_features(constexpr_cxx14 PRIVATE cxx_std_14) +if ("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES) + # C++17 changes some rules related to constexpr, check that it works + ei_add_test_internal(constexpr constexpr_cxx17) + target_compile_features(constexpr_cxx17 PRIVATE cxx_std_17) +endif() +if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES) + # C++20 changes some rules related to constexpr, check that it works + ei_add_test_internal(constexpr constexpr_cxx20) + target_compile_features(constexpr_cxx20 PRIVATE cxx_std_20) +endif() ei_add_test(constructor) ei_add_test(linearstructure) ei_add_test(integer_types) diff --git a/test/constexpr.cpp b/test/constexpr.cpp new file mode 100644 index 000000000..a327c14c4 --- /dev/null +++ b/test/constexpr.cpp @@ -0,0 +1,52 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2022 Alex Richardson +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "main.h" + +EIGEN_DECLARE_TEST(constexpr) { + // Clang accepts (some of) this code when using C++14/C++17, but GCC does not like + // the fact that `T array[Size]` inside Eigen::internal::plain_array is not initialized + // until after the constructor returns: + // error: member ‘Eigen::internal::plain_array::array’ must be initialized by mem-initializer in + // ‘constexpr’ constructor +#if EIGEN_COMP_CXXVER >= 20 || defined(__clang__) + constexpr Matrix3i mat({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + VERIFY_IS_EQUAL(mat.size(), 9); + VERIFY_IS_EQUAL(mat(0, 0), 1); + static_assert(mat.coeff(0,1) == 2); + constexpr Array33i arr({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + VERIFY_IS_EQUAL(arr(0, 0), 1); + VERIFY_IS_EQUAL(arr.size(), 9); + static_assert(arr.coeff(0,1) == 2); + // Also check dynamic size arrays/matrices with fixed-size storage (currently + // only works if all elements are initialized, since otherwise the compiler + // complains about uninitialized trailing elements. + constexpr Matrix dyn_mat({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + VERIFY_IS_EQUAL(dyn_mat.size(), 9); + VERIFY_IS_EQUAL(dyn_mat(0, 0), 1); + static_assert(dyn_mat.coeff(0,1) == 2); + constexpr Array dyn_arr({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + VERIFY_IS_EQUAL(dyn_arr(0, 0), 1); + VERIFY_IS_EQUAL(dyn_arr.size(), 9); + static_assert(dyn_arr.coeff(0,1) == 2); +#endif // EIGEN_COMP_CXXVER >= 20 || defined(__clang__) +} + +// Check that we can use the std::initializer_list constructor for constexpr variables. +#if EIGEN_COMP_CXXVER >= 20 +// EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT() will fail constexpr evaluation unless +// we have std::is_constant_evaluated(). +constexpr Matrix global_mat({{1, 2}, {3, 4}}); + +EIGEN_DECLARE_TEST(constexpr_global) { + VERIFY_IS_EQUAL(global_mat.size(), 4); + VERIFY_IS_EQUAL(global_mat(0, 0), 1); + static_assert(global_mat.coeff(0,0) == 1); +} +#endif // EIGEN_COMP_CXXVER >= 20