mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
turn some macros intro constexpr functions
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
0f36e42169
commit
c20e908ebc
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user