turn some macros intro constexpr functions

This commit is contained in:
Erik Schultheis
2021-12-10 19:27:01 +00:00
committed by Rasmus Munk Larsen
parent 0f36e42169
commit c20e908ebc
46 changed files with 200 additions and 151 deletions

View File

@@ -1107,35 +1107,6 @@ namespace Eigen {
typedef typename Base::PacketScalar PacketScalar;
#define EIGEN_PLAIN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
#define EIGEN_PLAIN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
// EIGEN_SIZE_MIN_PREFER_DYNAMIC gives the min between compile-time sizes. 0 has absolute priority, followed by 1,
// followed by Dynamic, followed by other finite values. The reason for giving Dynamic the priority over
// finite values is that min(3, Dynamic) should be Dynamic, since that could be anything between 0 and 3.
#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a,b) (((int)a == 0 || (int)b == 0) ? 0 \
: ((int)a == 1 || (int)b == 1) ? 1 \
: ((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \
: ((int)a <= (int)b) ? (int)a : (int)b)
// EIGEN_SIZE_MIN_PREFER_FIXED is a variant of EIGEN_SIZE_MIN_PREFER_DYNAMIC comparing MaxSizes. The difference is that finite values
// now have priority over Dynamic, so that min(3, Dynamic) gives 3. Indeed, whatever the actual value is
// (between 0 and 3), it is not more than 3.
#define EIGEN_SIZE_MIN_PREFER_FIXED(a,b) (((int)a == 0 || (int)b == 0) ? 0 \
: ((int)a == 1 || (int)b == 1) ? 1 \
: ((int)a == Dynamic && (int)b == Dynamic) ? Dynamic \
: ((int)a == Dynamic) ? (int)b \
: ((int)b == Dynamic) ? (int)a \
: ((int)a <= (int)b) ? (int)a : (int)b)
// see EIGEN_SIZE_MIN_PREFER_DYNAMIC. No need for a separate variant for MaxSizes here.
#define EIGEN_SIZE_MAX(a,b) (((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \
: ((int)a >= (int)b) ? (int)a : (int)b)
#define EIGEN_LOGICAL_XOR(a,b) (((a) || (b)) && !((a) && (b)))
#define EIGEN_IMPLIES(a,b) (!(a) || (b))
#if EIGEN_HAS_BUILTIN(__builtin_expect) || EIGEN_COMP_GNUC
#define EIGEN_PREDICT_FALSE(x) (__builtin_expect(x, false))
#define EIGEN_PREDICT_TRUE(x) (__builtin_expect(false || (x), true))

View File

@@ -579,6 +579,82 @@ bool not_equal_strict(const double& x,const double& y) { return std::not_equal_t
} // end namespace numext
namespace internal {
/// \internal Returns true if its argument is of integer or enum type.
/// FIXME this has the same purpose as `is_valid_index_type` in XprHelper.h
template<typename A>
constexpr bool is_int_or_enum_v = std::is_enum<A>::value || std::is_integral<A>::value;
/// \internal Gets the minimum of two values which may be integers or enums
template<typename A, typename B>
inline constexpr int plain_enum_min(A a, B b) {
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
return ((int) a <= (int) b) ? (int) a : (int) b;
}
/// \internal Gets the maximum of two values which may be integers or enums
template<typename A, typename B>
inline constexpr int plain_enum_max(A a, B b) {
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
return ((int) a >= (int) b) ? (int) a : (int) b;
}
/**
* \internal
* `min_size_prefer_dynamic` gives the min between compile-time sizes. 0 has absolute priority, followed by 1,
* followed by Dynamic, followed by other finite values. The reason for giving Dynamic the priority over
* finite values is that min(3, Dynamic) should be Dynamic, since that could be anything between 0 and 3.
*/
template<typename A, typename B>
inline constexpr int min_size_prefer_dynamic(A a, B b) {
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
if ((int) a == 0 || (int) b == 0) return 0;
if ((int) a == 1 || (int) b == 1) return 1;
if ((int) a == Dynamic || (int) b == Dynamic) return Dynamic;
return plain_enum_min(a, b);
}
/**
* \internal
* min_size_prefer_fixed is a variant of `min_size_prefer_dynamic` comparing MaxSizes. The difference is that finite values
* now have priority over Dynamic, so that min(3, Dynamic) gives 3. Indeed, whatever the actual value is
* (between 0 and 3), it is not more than 3.
*/
template<typename A, typename B>
inline constexpr int min_size_prefer_fixed(A a, B b) {
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
if ((int) a == 0 || (int) b == 0) return 0;
if ((int) a == 1 || (int) b == 1) return 1;
if ((int) a == Dynamic && (int) b == Dynamic) return Dynamic;
if ((int) a == Dynamic) return (int) b;
if ((int) b == Dynamic) return (int) a;
return plain_enum_min(a, b);
}
/// \internal see `min_size_prefer_fixed`. No need for a separate variant for MaxSizes here.
template<typename A, typename B>
inline constexpr int max_size_prefer_dynamic(A a, B b) {
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
if ((int) a == Dynamic || (int) b == Dynamic) return Dynamic;
return plain_enum_max(a, b);
}
/// \internal Calculate logical XOR at compile time
inline constexpr bool logical_xor(bool a, bool b) {
return (a || b) && !(a && b);
}
/// \internal Calculate logical IMPLIES at compile time
inline constexpr bool check_implication(bool a, bool b) {
return !a || b;
}
} // end namespace internal
} // end namespace Eigen
#endif // EIGEN_META_H

View File

@@ -646,8 +646,9 @@ struct plain_col_type
template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
struct plain_diag_type
{
enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
enum { diag_size = internal::min_size_prefer_dynamic(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
max_diag_size = min_size_prefer_fixed(ExpressionType::MaxRowsAtCompileTime,
ExpressionType::MaxColsAtCompileTime)
};
typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType;
typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType;