Selectively add constexpr to Core expression template scaffolding

libeigen/eigen!2184

Closes #3041

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
Rasmus Munk Larsen
2026-02-24 19:59:10 -08:00
parent 34092d2788
commit 61895c5978
70 changed files with 986 additions and 841 deletions

View File

@@ -43,12 +43,12 @@ struct general_matrix_vector_product;
template <typename From, typename To>
struct get_factor {
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE To run(const From& x) { return To(x); }
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE To run(const From& x) { return To(x); }
};
template <typename Scalar>
struct get_factor<Scalar, typename NumTraits<Scalar>::Real> {
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) {
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) {
return numext::real(x);
}
};
@@ -56,9 +56,9 @@ struct get_factor<Scalar, typename NumTraits<Scalar>::Real> {
template <typename Scalar, typename Index>
class BlasVectorMapper {
public:
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasVectorMapper(Scalar* data) : m_data(data) {}
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE BlasVectorMapper(Scalar* data) : m_data(data) {}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar operator()(Index i) const { return m_data[i]; }
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE Scalar operator()(Index i) const { return m_data[i]; }
template <typename Packet, int AlignmentType>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet load(Index i) const {
return ploadt<Packet, AlignmentType>(m_data + i);
@@ -79,14 +79,14 @@ class BlasLinearMapper;
template <typename Scalar, typename Index, int AlignmentType>
class BlasLinearMapper<Scalar, Index, AlignmentType> {
public:
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar* data, Index incr = 1) : m_data(data) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar* data, Index incr = 1) : m_data(data) {
EIGEN_ONLY_USED_FOR_DEBUG(incr);
eigen_assert(incr == 1);
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index i) const { internal::prefetch(&operator()(i)); }
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const { return m_data[i]; }
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const { return m_data[i]; }
template <typename PacketType>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacket(Index i) const {
@@ -178,27 +178,27 @@ class blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, 1> {
typedef blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType> SubMapper;
typedef BlasVectorMapper<Scalar, Index> VectorMapper;
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr = 1)
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr = 1)
: m_data(data), m_stride(stride) {
EIGEN_ONLY_USED_FOR_DEBUG(incr);
eigen_assert(incr == 1);
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubMapper getSubMapper(Index i, Index j) const {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE SubMapper getSubMapper(Index i, Index j) const {
return SubMapper(&operator()(i, j), m_stride);
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
return LinearMapper(&operator()(i, j));
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE VectorMapper getVectorMapper(Index i, Index j) const {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE VectorMapper getVectorMapper(Index i, Index j) const {
return VectorMapper(&operator()(i, j));
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index i, Index j) const { internal::prefetch(&operator()(i, j)); }
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const {
return m_data[StorageOrder == RowMajor ? j + i * m_stride : i + j * m_stride];
}
@@ -239,8 +239,8 @@ class blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, 1> {
return pgather<Scalar, SubPacket>(&operator()(i, j), m_stride);
}
EIGEN_DEVICE_FUNC const Index stride() const { return m_stride; }
EIGEN_DEVICE_FUNC const Index incr() const { return 1; }
EIGEN_DEVICE_FUNC constexpr const Index stride() const { return m_stride; }
EIGEN_DEVICE_FUNC constexpr const Index incr() const { return 1; }
EIGEN_DEVICE_FUNC constexpr const Scalar* data() const { return m_data; }
EIGEN_DEVICE_FUNC Index firstAligned(Index size) const {
@@ -268,11 +268,14 @@ class blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, 1> {
template <typename Scalar, typename Index, int AlignmentType, int Incr>
class BlasLinearMapper {
public:
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar* data, Index incr) : m_data(data), m_incr(incr) {}
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar* data, Index incr)
: m_data(data), m_incr(incr) {}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(int i) const { internal::prefetch(&operator()(i)); }
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const { return m_data[i * m_incr.value()]; }
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const {
return m_data[i * m_incr.value()];
}
template <typename PacketType>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacket(Index i) const {
@@ -306,20 +309,20 @@ class blas_data_mapper {
typedef BlasLinearMapper<Scalar, Index, AlignmentType, Incr> LinearMapper;
typedef blas_data_mapper SubMapper;
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr)
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr)
: m_data(data), m_stride(stride), m_incr(incr) {}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubMapper getSubMapper(Index i, Index j) const {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE SubMapper getSubMapper(Index i, Index j) const {
return SubMapper(&operator()(i, j), m_stride, m_incr.value());
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
return LinearMapper(&operator()(i, j), m_incr.value());
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index i, Index j) const { internal::prefetch(&operator()(i, j)); }
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const {
return m_data[StorageOrder == RowMajor ? j * m_incr.value() + i * m_stride : i * m_incr.value() + j * m_stride];
}
@@ -428,8 +431,8 @@ class blas_data_mapper {
spb.store(this, i, j, block);
}
EIGEN_DEVICE_FUNC const Index stride() const { return m_stride; }
EIGEN_DEVICE_FUNC const Index incr() const { return m_incr.value(); }
EIGEN_DEVICE_FUNC constexpr const Index stride() const { return m_stride; }
EIGEN_DEVICE_FUNC constexpr const Index incr() const { return m_incr.value(); }
EIGEN_DEVICE_FUNC constexpr Scalar* data() const { return m_data; }
protected:
@@ -567,18 +570,18 @@ struct blas_traits<const T> : blas_traits<T> {};
template <typename T, bool HasUsableDirectAccess = blas_traits<T>::HasUsableDirectAccess>
struct extract_data_selector {
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static const typename T::Scalar* run(const T& m) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE static const typename T::Scalar* run(const T& m) {
return blas_traits<T>::extract(m).data();
}
};
template <typename T>
struct extract_data_selector<T, false> {
EIGEN_DEVICE_FUNC static typename T::Scalar* run(const T&) { return 0; }
EIGEN_DEVICE_FUNC constexpr static typename T::Scalar* run(const T&) { return 0; }
};
template <typename T>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const typename T::Scalar* extract_data(const T& m) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE const typename T::Scalar* extract_data(const T& m) {
return extract_data_selector<T>::run(m);
}
@@ -588,30 +591,31 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const typename T::Scalar* extract_data(con
*/
template <typename ResScalar, typename Lhs, typename Rhs>
struct combine_scalar_factors_impl {
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static ResScalar run(const Lhs& lhs, const Rhs& rhs) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE static ResScalar run(const Lhs& lhs, const Rhs& rhs) {
return blas_traits<Lhs>::extractScalarFactor(lhs) * blas_traits<Rhs>::extractScalarFactor(rhs);
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static ResScalar run(const ResScalar& alpha, const Lhs& lhs, const Rhs& rhs) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE static ResScalar run(const ResScalar& alpha, const Lhs& lhs,
const Rhs& rhs) {
return alpha * blas_traits<Lhs>::extractScalarFactor(lhs) * blas_traits<Rhs>::extractScalarFactor(rhs);
}
};
template <typename Lhs, typename Rhs>
struct combine_scalar_factors_impl<bool, Lhs, Rhs> {
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static bool run(const Lhs& lhs, const Rhs& rhs) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE static bool run(const Lhs& lhs, const Rhs& rhs) {
return blas_traits<Lhs>::extractScalarFactor(lhs) && blas_traits<Rhs>::extractScalarFactor(rhs);
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static bool run(const bool& alpha, const Lhs& lhs, const Rhs& rhs) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE static bool run(const bool& alpha, const Lhs& lhs, const Rhs& rhs) {
return alpha && blas_traits<Lhs>::extractScalarFactor(lhs) && blas_traits<Rhs>::extractScalarFactor(rhs);
}
};
template <typename ResScalar, typename Lhs, typename Rhs>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE ResScalar combine_scalar_factors(const ResScalar& alpha, const Lhs& lhs,
const Rhs& rhs) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE ResScalar combine_scalar_factors(const ResScalar& alpha, const Lhs& lhs,
const Rhs& rhs) {
return combine_scalar_factors_impl<ResScalar, Lhs, Rhs>::run(alpha, lhs, rhs);
}
template <typename ResScalar, typename Lhs, typename Rhs>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE ResScalar combine_scalar_factors(const Lhs& lhs, const Rhs& rhs) {
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE ResScalar combine_scalar_factors(const Lhs& lhs, const Rhs& rhs) {
return combine_scalar_factors_impl<ResScalar, Lhs, Rhs>::run(lhs, rhs);
}

View File

@@ -22,21 +22,21 @@ namespace Eigen {
*
* Changing the value of Dynamic breaks the ABI, as Dynamic is often used as a template parameter for Matrix.
*/
const int Dynamic = -1;
constexpr int Dynamic = -1;
/** This value means that a signed quantity (e.g., a signed index) is not known at compile-time, and that instead its
* value has to be specified at runtime.
*/
const int DynamicIndex = 0xffffff;
constexpr int DynamicIndex = 0xffffff;
/** This value means that the requested value is not defined.
*/
const int Undefined = 0xfffffe;
constexpr int Undefined = 0xfffffe;
/** This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm<int>().
* The value Infinity there means the L-infinity norm.
*/
const int Infinity = -1;
constexpr int Infinity = -1;
/** This value means that the cost to evaluate an expression coefficient is either very expensive or
* cannot be known at compile time.
@@ -45,7 +45,7 @@ const int Infinity = -1;
* and very very expensive expressions. It thus must also be large enough to make sure unrolling won't happen and that
* sub expressions will be evaluated, but not too large to avoid overflow.
*/
const int HugeCost = 10000;
constexpr int HugeCost = 10000;
/** \defgroup flags Flags
* \ingroup Core_Module
@@ -67,16 +67,16 @@ const int HugeCost = 10000;
* For an expression, this determines the storage order of
* the matrix created by evaluation of that expression.
* \sa \blank \ref TopicStorageOrders */
const unsigned int RowMajorBit = 0x1;
constexpr unsigned int RowMajorBit = 0x1;
/** \ingroup flags
* means the expression should be evaluated by the calling expression */
const unsigned int EvalBeforeNestingBit = 0x2;
constexpr unsigned int EvalBeforeNestingBit = 0x2;
/** \ingroup flags
* \deprecated
* means the expression should be evaluated before any assignment */
EIGEN_DEPRECATED const unsigned int EvalBeforeAssigningBit = 0x4; // FIXME deprecated
EIGEN_DEPRECATED constexpr unsigned int EvalBeforeAssigningBit = 0x4; // FIXME deprecated
/** \ingroup flags
*
@@ -94,7 +94,7 @@ EIGEN_DEPRECATED const unsigned int EvalBeforeAssigningBit = 0x4; // FIXME depr
* \note This bit can be set regardless of whether vectorization is actually enabled.
* To check for actual vectorizability, see \a ActualPacketAccessBit.
*/
const unsigned int PacketAccessBit = 0x8;
constexpr unsigned int PacketAccessBit = 0x8;
#ifdef EIGEN_VECTORIZE
/** \ingroup flags
@@ -105,9 +105,9 @@ const unsigned int PacketAccessBit = 0x8;
* If vectorization is not enabled (EIGEN_VECTORIZE is not defined) this constant
* is set to the value 0.
*/
const unsigned int ActualPacketAccessBit = PacketAccessBit;
constexpr unsigned int ActualPacketAccessBit = PacketAccessBit;
#else
const unsigned int ActualPacketAccessBit = 0x0;
constexpr unsigned int ActualPacketAccessBit = 0x0;
#endif
/** \ingroup flags
@@ -130,7 +130,7 @@ const unsigned int ActualPacketAccessBit = 0x0;
* Product is a vector expression. Thus, vector Product expressions allow index-based coefficient access but
* not index-based packet access, so they don't have the LinearAccessBit.
*/
const unsigned int LinearAccessBit = 0x10;
constexpr unsigned int LinearAccessBit = 0x10;
/** \ingroup flags
*
@@ -145,7 +145,7 @@ const unsigned int LinearAccessBit = 0x10;
* Expressions having LvalueBit also have their coeff() method returning a const reference instead of returning a new
* value.
*/
const unsigned int LvalueBit = 0x20;
constexpr unsigned int LvalueBit = 0x20;
/** \ingroup flags
*
@@ -156,7 +156,7 @@ const unsigned int LvalueBit = 0x20;
*
* See the comment on LvalueBit for an explanation of how LvalueBit and DirectAccessBit are mutually orthogonal.
*/
const unsigned int DirectAccessBit = 0x40;
constexpr unsigned int DirectAccessBit = 0x40;
/** \deprecated \ingroup flags
*
@@ -168,9 +168,9 @@ const unsigned int DirectAccessBit = 0x40;
* expression.packet<Aligned>(0);
* \endcode
*/
EIGEN_DEPRECATED const unsigned int AlignedBit = 0x80;
EIGEN_DEPRECATED constexpr unsigned int AlignedBit = 0x80;
const unsigned int NestByRefBit = 0x100;
constexpr unsigned int NestByRefBit = 0x100;
/** \ingroup flags
*
@@ -179,7 +179,7 @@ const unsigned int NestByRefBit = 0x100;
* The precise choice will be decided at evaluation time or when
* combined with other expressions.
* \sa \blank \ref RowMajorBit, \ref TopicStorageOrders */
const unsigned int NoPreferredStorageOrderBit = 0x200;
constexpr unsigned int NoPreferredStorageOrderBit = 0x200;
/** \ingroup flags
*
@@ -192,10 +192,10 @@ const unsigned int NoPreferredStorageOrderBit = 0x200;
inline const Index* innerNonZeroPtr() const;
\endcode
*/
const unsigned int CompressedAccessBit = 0x400;
constexpr unsigned int CompressedAccessBit = 0x400;
// list of flags that are inherited by default
const unsigned int HereditaryBits = RowMajorBit | EvalBeforeNestingBit;
constexpr unsigned int HereditaryBits = RowMajorBit | EvalBeforeNestingBit;
/** \defgroup enums Enumerations
* \ingroup Core_Module

View File

@@ -144,8 +144,8 @@ template <int N>
class VariableAndFixedInt {
public:
static const int value = N;
operator int() const { return m_value; }
VariableAndFixedInt(int val) { m_value = val; }
constexpr operator int() const { return m_value; }
constexpr VariableAndFixedInt(int val) : m_value(val) {}
protected:
int m_value;
@@ -172,7 +172,7 @@ struct get_fixed_value<variable_if_dynamic<T, N>, Default> {
};
template <typename T>
EIGEN_DEVICE_FUNC Index get_runtime_value(const T &x) {
EIGEN_DEVICE_FUNC constexpr Index get_runtime_value(const T &x) {
return x;
}

View File

@@ -1276,7 +1276,7 @@ EIGEN_DEVICE_FUNC constexpr void ignore_unused_variable(const T&) {}
#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD, OPNAME) \
template <typename OtherDerived> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE( \
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE( \
Derived, OtherDerived, OPNAME)(METHOD)(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const { \
return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived, OtherDerived, OPNAME)(derived(), other.derived()); \
}
@@ -1297,7 +1297,7 @@ EIGEN_DEVICE_FUNC constexpr void ignore_unused_variable(const T&) {}
#define EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(METHOD, OPNAME) \
template <typename T> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE( \
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE( \
Derived, \
typename internal::promote_scalar_arg<Scalar EIGEN_COMMA T EIGEN_COMMA EIGEN_SCALAR_BINARY_SUPPORTED( \
OPNAME, Scalar, T)>::type, \
@@ -1311,7 +1311,7 @@ EIGEN_DEVICE_FUNC constexpr void ignore_unused_variable(const T&) {}
#define EIGEN_MAKE_SCALAR_BINARY_OP_ONTHELEFT(METHOD, OPNAME) \
template <typename T> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE friend const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE( \
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE friend const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE( \
typename internal::promote_scalar_arg<Scalar EIGEN_COMMA T EIGEN_COMMA EIGEN_SCALAR_BINARY_SUPPORTED( \
OPNAME, T, Scalar)>::type, \
Derived, OPNAME)(METHOD)(const T& scalar, const StorageBaseType& matrix) { \
@@ -1356,10 +1356,10 @@ EIGEN_DEVICE_FUNC constexpr void ignore_unused_variable(const T&) {}
namespace Eigen {
namespace internal {
EIGEN_DEVICE_FUNC inline bool all() { return true; }
EIGEN_DEVICE_FUNC constexpr bool all() { return true; }
template <typename T, typename... Ts>
EIGEN_DEVICE_FUNC bool all(T t, Ts... ts) {
EIGEN_DEVICE_FUNC constexpr bool all(T t, Ts... ts) {
return t && all(ts...);
}

View File

@@ -444,14 +444,14 @@ namespace numext {
#if defined(EIGEN_GPU_COMPILE_PHASE)
template <typename T>
EIGEN_DEVICE_FUNC void swap(T& a, T& b) {
EIGEN_DEVICE_FUNC constexpr void swap(T& a, T& b) {
T tmp = b;
b = a;
a = tmp;
}
#else
template <typename T>
EIGEN_STRONG_INLINE void swap(T& a, T& b) {
constexpr EIGEN_STRONG_INLINE void swap(T& a, T& b) {
std::swap(a, b);
}
#endif
@@ -462,7 +462,7 @@ using std::numeric_limits;
template <typename X, typename Y, bool XIsInteger = NumTraits<X>::IsInteger, bool XIsSigned = NumTraits<X>::IsSigned,
bool YIsInteger = NumTraits<Y>::IsInteger, bool YIsSigned = NumTraits<Y>::IsSigned>
struct equal_strict_impl {
static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) { return x == y; }
static constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) { return x == y; }
};
template <typename X, typename Y>
struct equal_strict_impl<X, Y, true, false, true, true> {
@@ -470,7 +470,7 @@ struct equal_strict_impl<X, Y, true, false, true, true> {
// Y is a signed integer
// if Y is non-negative, it may be represented exactly as its unsigned counterpart.
using UnsignedY = typename internal::make_unsigned<Y>::type;
static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) {
static constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) {
return y < Y(0) ? false : (x == static_cast<UnsignedY>(y));
}
};
@@ -478,7 +478,7 @@ template <typename X, typename Y>
struct equal_strict_impl<X, Y, true, true, true, false> {
// X is a signed integer
// Y is an unsigned integer
static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) {
static constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool run(const X& x, const Y& y) {
return equal_strict_impl<Y, X>::run(y, x);
}
};
@@ -486,18 +486,18 @@ struct equal_strict_impl<X, Y, true, true, true, false> {
// The aim of the following functions is to bypass -Wfloat-equal warnings
// when we really want a strict equality comparison on floating points.
template <typename X, typename Y>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X& x, const Y& y) {
constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X& x, const Y& y) {
return equal_strict_impl<X, Y>::run(x, y);
}
#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
template <>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const float& x, const float& y) {
constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const float& x, const float& y) {
return std::equal_to<float>()(x, y);
}
template <>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const double& x, const double& y) {
constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const double& x, const double& y) {
return std::equal_to<double>()(x, y);
}
#endif
@@ -507,7 +507,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const double& x, const d
* Use this to to bypass -Wfloat-equal warnings when exact zero is what needs to be tested.
*/
template <typename X>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X& x) {
constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X& x) {
return equal_strict(x, typename NumTraits<X>::Literal{0});
}
@@ -516,23 +516,23 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X& x) {
* Use this to to bypass -Wfloat-equal warnings when exact one is what needs to be tested.
*/
template <typename X>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_one(const X& x) {
constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_one(const X& x) {
return equal_strict(x, typename NumTraits<X>::Literal{1});
}
template <typename X, typename Y>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const X& x, const Y& y) {
constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const X& x, const Y& y) {
return !equal_strict_impl<X, Y>::run(x, y);
}
#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
template <>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const float& x, const float& y) {
constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const float& x, const float& y) {
return std::not_equal_to<float>()(x, y);
}
template <>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const double& x, const double& y) {
constexpr EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const double& x, const double& y) {
return std::not_equal_to<double>()(x, y);
}
#endif
@@ -543,11 +543,11 @@ namespace internal {
template <typename Scalar>
struct is_identically_zero_impl {
static inline bool run(const Scalar& s) { return numext::is_exactly_zero(s); }
static constexpr bool run(const Scalar& s) { return numext::is_exactly_zero(s); }
};
template <typename Scalar>
EIGEN_STRONG_INLINE bool is_identically_zero(const Scalar& s) {
constexpr EIGEN_STRONG_INLINE bool is_identically_zero(const Scalar& s) {
return is_identically_zero_impl<Scalar>::run(s);
}

View File

@@ -152,7 +152,7 @@ struct promote_index_type {
template <typename T, int Value>
class variable_if_dynamic {
public:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) {
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) {
EIGEN_ONLY_USED_FOR_DEBUG(v);
eigen_assert(v == T(Value));
}
@@ -169,9 +169,9 @@ class variable_if_dynamic<T, Dynamic> {
T m_value;
public:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value = 0) noexcept : m_value(value) {}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return m_value; }
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value = 0) noexcept : m_value(value) {}
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE T value() const { return m_value; }
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE operator T() const { return m_value; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
};
@@ -180,12 +180,12 @@ class variable_if_dynamic<T, Dynamic> {
template <typename T, int Value>
class variable_if_dynamicindex {
public:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) {
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) {
EIGEN_ONLY_USED_FOR_DEBUG(v);
eigen_assert(v == T(Value));
}
EIGEN_DEVICE_FUNC static constexpr T value() { return T(Value); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void setValue(T) {}
};
template <typename T>
@@ -194,8 +194,8 @@ class variable_if_dynamicindex<T, DynamicIndex> {
EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); }
public:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T value) : m_value(value) {}
EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const { return m_value; }
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T value) : m_value(value) {}
EIGEN_DEVICE_FUNC constexpr T EIGEN_STRONG_INLINE value() const { return m_value; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
};