Simplify and modernize XprHelper.h

libeigen/eigen!2243

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
Rasmus Munk Larsen
2026-03-04 10:33:05 -08:00
parent dd826edb42
commit eea4d31f58

View File

@@ -96,7 +96,7 @@ struct promote_scalar_arg;
template <typename S, typename T> template <typename S, typename T>
struct promote_scalar_arg<S, T, true> { struct promote_scalar_arg<S, T, true> {
typedef T type; using type = T;
}; };
// Recursively check safe conversion to PromotedType, and then ExprScalar if they are different. // Recursively check safe conversion to PromotedType, and then ExprScalar if they are different.
@@ -112,7 +112,7 @@ struct promote_scalar_arg<S, T, false> : promote_scalar_arg_unsupported<S, T, ty
// We found a match! // We found a match!
template <typename S, typename T, typename PromotedType> template <typename S, typename T, typename PromotedType>
struct promote_scalar_arg_unsupported<S, T, PromotedType, true, true> { struct promote_scalar_arg_unsupported<S, T, PromotedType, true, true> {
typedef PromotedType type; using type = PromotedType;
}; };
// No match, but no real-to-integer issues, and ExprScalar and current PromotedType are different, // No match, but no real-to-integer issues, and ExprScalar and current PromotedType are different,
@@ -131,8 +131,7 @@ struct promote_scalar_arg_unsupported<S, T, S, false, true> {};
// classes inheriting no_assignment_operator don't generate a default operator=. // classes inheriting no_assignment_operator don't generate a default operator=.
class no_assignment_operator { class no_assignment_operator {
private: no_assignment_operator& operator=(const no_assignment_operator&) = delete;
no_assignment_operator& operator=(const no_assignment_operator&);
protected: protected:
EIGEN_DEFAULT_COPY_CONSTRUCTOR(no_assignment_operator) EIGEN_DEFAULT_COPY_CONSTRUCTOR(no_assignment_operator)
@@ -142,7 +141,7 @@ class no_assignment_operator {
/** \internal return the index type with the largest number of bits */ /** \internal return the index type with the largest number of bits */
template <typename I1, typename I2> template <typename I1, typename I2>
struct promote_index_type { struct promote_index_type {
typedef std::conditional_t<(sizeof(I1) < sizeof(I2)), I2, I1> type; using type = std::conditional_t<(sizeof(I1) < sizeof(I2)), I2, I1>;
}; };
/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around a T variable that /** \internal If the template parameter Value is Dynamic, this class is just a wrapper around a T variable that
@@ -275,17 +274,17 @@ struct find_best_packet_helper;
template <int Size, typename PacketType> template <int Size, typename PacketType>
struct find_best_packet_helper<Size, PacketType, true> { struct find_best_packet_helper<Size, PacketType, true> {
typedef PacketType type; using type = PacketType;
}; };
template <int Size, typename PacketType> template <int Size, typename PacketType>
struct find_best_packet_helper<Size, PacketType, false> { struct find_best_packet_helper<Size, PacketType, false> {
typedef typename find_best_packet_helper<Size, typename unpacket_traits<PacketType>::half>::type type; using type = typename find_best_packet_helper<Size, typename unpacket_traits<PacketType>::half>::type;
}; };
template <typename T, int Size> template <typename T, int Size>
struct find_best_packet { struct find_best_packet {
typedef typename find_best_packet_helper<Size, typename packet_traits<T>::type>::type type; using type = typename find_best_packet_helper<Size, typename packet_traits<T>::type>::type;
}; };
template <int Size, typename PacketType, template <int Size, typename PacketType,
@@ -347,17 +346,16 @@ template <typename Scalar_, int Rows_, int Cols_,
: (Cols_ == 1 && Rows_ != 1) ? ColMajor : (Cols_ == 1 && Rows_ != 1) ? ColMajor
: EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION), : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION),
int MaxRows_ = Rows_, int MaxCols_ = Cols_> int MaxRows_ = Rows_, int MaxCols_ = Cols_>
class make_proper_matrix_type { struct make_proper_matrix_type {
enum { private:
IsColVector = Cols_ == 1 && Rows_ != 1, static constexpr bool IsColVector = Cols_ == 1 && Rows_ != 1;
IsRowVector = Rows_ == 1 && Cols_ != 1, static constexpr bool IsRowVector = Rows_ == 1 && Cols_ != 1;
Options = IsColVector ? (Options_ | ColMajor) & ~RowMajor static constexpr int Options = IsColVector ? (Options_ | ColMajor) & ~RowMajor
: IsRowVector ? (Options_ | RowMajor) & ~ColMajor : IsRowVector ? (Options_ | RowMajor) & ~ColMajor
: Options_ : Options_;
};
public: public:
typedef Matrix<Scalar_, Rows_, Cols_, Options, MaxRows_, MaxCols_> type; using type = Matrix<Scalar_, Rows_, Cols_, Options, MaxRows_, MaxCols_>;
}; };
constexpr unsigned compute_matrix_flags(int Options) { constexpr unsigned compute_matrix_flags(int Options) {
@@ -389,32 +387,30 @@ template <typename T, typename BaseClassType, int Flags>
struct plain_matrix_type_dense; struct plain_matrix_type_dense;
template <typename T> template <typename T>
struct plain_matrix_type<T, Dense> { struct plain_matrix_type<T, Dense> {
typedef typename plain_matrix_type_dense<T, typename traits<T>::XprKind, traits<T>::Flags>::type type; using type = typename plain_matrix_type_dense<T, typename traits<T>::XprKind, traits<T>::Flags>::type;
}; };
template <typename T> template <typename T>
struct plain_matrix_type<T, DiagonalShape> { struct plain_matrix_type<T, DiagonalShape> {
typedef typename T::PlainObject type; using type = typename T::PlainObject;
}; };
template <typename T> template <typename T>
struct plain_matrix_type<T, SkewSymmetricShape> { struct plain_matrix_type<T, SkewSymmetricShape> {
typedef typename T::PlainObject type; using type = typename T::PlainObject;
}; };
template <typename T, int Flags> template <typename T, int Flags>
struct plain_matrix_type_dense<T, MatrixXpr, Flags> { struct plain_matrix_type_dense<T, MatrixXpr, Flags> {
typedef Matrix<typename traits<T>::Scalar, traits<T>::RowsAtCompileTime, traits<T>::ColsAtCompileTime, using type = Matrix<typename traits<T>::Scalar, traits<T>::RowsAtCompileTime, traits<T>::ColsAtCompileTime,
AutoAlign | (Flags & RowMajorBit ? RowMajor : ColMajor), traits<T>::MaxRowsAtCompileTime, AutoAlign | (Flags & RowMajorBit ? RowMajor : ColMajor), traits<T>::MaxRowsAtCompileTime,
traits<T>::MaxColsAtCompileTime> traits<T>::MaxColsAtCompileTime>;
type;
}; };
template <typename T, int Flags> template <typename T, int Flags>
struct plain_matrix_type_dense<T, ArrayXpr, Flags> { struct plain_matrix_type_dense<T, ArrayXpr, Flags> {
typedef Array<typename traits<T>::Scalar, traits<T>::RowsAtCompileTime, traits<T>::ColsAtCompileTime, using type = Array<typename traits<T>::Scalar, traits<T>::RowsAtCompileTime, traits<T>::ColsAtCompileTime,
AutoAlign | (Flags & RowMajorBit ? RowMajor : ColMajor), traits<T>::MaxRowsAtCompileTime, AutoAlign | (Flags & RowMajorBit ? RowMajor : ColMajor), traits<T>::MaxRowsAtCompileTime,
traits<T>::MaxColsAtCompileTime> traits<T>::MaxColsAtCompileTime>;
type;
}; };
/* eval : the return type of eval(). For matrices, this is just a const reference /* eval : the return type of eval(). For matrices, this is just a const reference
@@ -426,36 +422,28 @@ struct eval;
template <typename T> template <typename T>
struct eval<T, Dense> { struct eval<T, Dense> {
typedef typename plain_matrix_type<T>::type type; using type = typename plain_matrix_type<T>::type;
// typedef typename T::PlainObject type;
// typedef T::Matrix<typename traits<T>::Scalar,
// traits<T>::RowsAtCompileTime,
// traits<T>::ColsAtCompileTime,
// AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
// traits<T>::MaxRowsAtCompileTime,
// traits<T>::MaxColsAtCompileTime
// > type;
}; };
template <typename T> template <typename T>
struct eval<T, DiagonalShape> { struct eval<T, DiagonalShape> {
typedef typename plain_matrix_type<T>::type type; using type = typename plain_matrix_type<T>::type;
}; };
template <typename T> template <typename T>
struct eval<T, SkewSymmetricShape> { struct eval<T, SkewSymmetricShape> {
typedef typename plain_matrix_type<T>::type type; using type = typename plain_matrix_type<T>::type;
}; };
// for matrices, no need to evaluate, just use a const reference to avoid a useless copy // for matrices, no need to evaluate, just use a const reference to avoid a useless copy
template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_> template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
struct eval<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>, Dense> { struct eval<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>, Dense> {
typedef const Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>& type; using type = const Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>&;
}; };
template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_> template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
struct eval<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>, Dense> { struct eval<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>, Dense> {
typedef const Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>& type; using type = const Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>&;
}; };
/* similar to plain_matrix_type, but using the evaluator's Flags */ /* similar to plain_matrix_type, but using the evaluator's Flags */
@@ -464,37 +452,31 @@ struct plain_object_eval;
template <typename T> template <typename T>
struct plain_object_eval<T, Dense> { struct plain_object_eval<T, Dense> {
typedef typename plain_matrix_type_dense<T, typename traits<T>::XprKind, evaluator<T>::Flags>::type type; using type = typename plain_matrix_type_dense<T, typename traits<T>::XprKind, evaluator<T>::Flags>::type;
}; };
/* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major /* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
*/ */
template <typename T> template <typename T>
struct plain_matrix_type_column_major { struct plain_matrix_type_column_major {
enum { static constexpr int Rows = traits<T>::RowsAtCompileTime;
Rows = traits<T>::RowsAtCompileTime, static constexpr int Cols = traits<T>::ColsAtCompileTime;
Cols = traits<T>::ColsAtCompileTime, static constexpr int MaxRows = traits<T>::MaxRowsAtCompileTime;
MaxRows = traits<T>::MaxRowsAtCompileTime, static constexpr int MaxCols = traits<T>::MaxColsAtCompileTime;
MaxCols = traits<T>::MaxColsAtCompileTime using type = Matrix<typename traits<T>::Scalar, Rows, Cols, (MaxRows == 1 && MaxCols != 1) ? RowMajor : ColMajor,
}; MaxRows, MaxCols>;
typedef Matrix<typename traits<T>::Scalar, Rows, Cols, (MaxRows == 1 && MaxCols != 1) ? RowMajor : ColMajor, MaxRows,
MaxCols>
type;
}; };
/* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major /* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
*/ */
template <typename T> template <typename T>
struct plain_matrix_type_row_major { struct plain_matrix_type_row_major {
enum { static constexpr int Rows = traits<T>::RowsAtCompileTime;
Rows = traits<T>::RowsAtCompileTime, static constexpr int Cols = traits<T>::ColsAtCompileTime;
Cols = traits<T>::ColsAtCompileTime, static constexpr int MaxRows = traits<T>::MaxRowsAtCompileTime;
MaxRows = traits<T>::MaxRowsAtCompileTime, static constexpr int MaxCols = traits<T>::MaxColsAtCompileTime;
MaxCols = traits<T>::MaxColsAtCompileTime using type = Matrix<typename traits<T>::Scalar, Rows, Cols, (MaxCols == 1 && MaxRows != 1) ? ColMajor : RowMajor,
}; MaxRows, MaxCols>;
typedef Matrix<typename traits<T>::Scalar, Rows, Cols, (MaxCols == 1 && MaxRows != 1) ? ColMajor : RowMajor, MaxRows,
MaxCols>
type;
}; };
/** \internal The reference selector for template expressions. The idea is that we don't /** \internal The reference selector for template expressions. The idea is that we don't
@@ -502,15 +484,9 @@ struct plain_matrix_type_row_major {
* objects which should generate no copying overhead. */ * objects which should generate no copying overhead. */
template <typename T> template <typename T>
struct ref_selector { struct ref_selector {
typedef std::conditional_t<bool(traits<T>::Flags& NestByRefBit), T const&, const T> type; using type = std::conditional_t<bool(traits<T>::Flags& NestByRefBit), T const&, const T>;
typedef std::conditional_t<bool(traits<T>::Flags& NestByRefBit), T&, T> non_const_type; using non_const_type = std::conditional_t<bool(traits<T>::Flags& NestByRefBit), T&, T>;
};
/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */
template <typename T1, typename T2>
struct transfer_constness {
typedef std::conditional_t<bool(internal::is_const<T1>::value), add_const_on_value_type_t<T2>, T2> type;
}; };
// However, we still need a mechanism to detect whether an expression which is evaluated multiple time // However, we still need a mechanism to detect whether an expression which is evaluated multiple time
@@ -544,14 +520,9 @@ struct nested_eval {
Evaluate = (int(evaluator<T>::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval)) Evaluate = (int(evaluator<T>::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval))
}; };
typedef std::conditional_t<Evaluate, PlainObject, typename ref_selector<T>::type> type; using type = std::conditional_t<Evaluate, PlainObject, typename ref_selector<T>::type>;
}; };
template <typename T>
EIGEN_DEVICE_FUNC inline T* const_cast_ptr(const T* ptr) {
return const_cast<T*>(ptr);
}
template <typename Derived, typename XprKind = typename traits<Derived>::XprKind> template <typename Derived, typename XprKind = typename traits<Derived>::XprKind>
struct dense_xpr_base { struct dense_xpr_base {
/* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the
@@ -560,12 +531,12 @@ struct dense_xpr_base {
template <typename Derived> template <typename Derived>
struct dense_xpr_base<Derived, MatrixXpr> { struct dense_xpr_base<Derived, MatrixXpr> {
typedef MatrixBase<Derived> type; using type = MatrixBase<Derived>;
}; };
template <typename Derived> template <typename Derived>
struct dense_xpr_base<Derived, ArrayXpr> { struct dense_xpr_base<Derived, ArrayXpr> {
typedef ArrayBase<Derived> type; using type = ArrayBase<Derived>;
}; };
template <typename Derived, typename XprKind = typename traits<Derived>::XprKind, template <typename Derived, typename XprKind = typename traits<Derived>::XprKind,
@@ -574,15 +545,15 @@ struct generic_xpr_base;
template <typename Derived, typename XprKind> template <typename Derived, typename XprKind>
struct generic_xpr_base<Derived, XprKind, Dense> { struct generic_xpr_base<Derived, XprKind, Dense> {
typedef typename dense_xpr_base<Derived, XprKind>::type type; using type = typename dense_xpr_base<Derived, XprKind>::type;
}; };
template <typename XprType, typename CastType> template <typename XprType, typename CastType>
struct cast_return_type { struct cast_return_type {
typedef typename XprType::Scalar CurrentScalarType; using CurrentScalarType = typename XprType::Scalar;
typedef remove_all_t<CastType> CastType_; using CastType_ = remove_all_t<CastType>;
typedef typename CastType_::Scalar NewScalarType; using NewScalarType = typename CastType_::Scalar;
typedef std::conditional_t<is_same<CurrentScalarType, NewScalarType>::value, const XprType&, CastType> type; using type = std::conditional_t<is_same<CurrentScalarType, NewScalarType>::value, const XprType&, CastType>;
}; };
template <typename A, typename B> template <typename A, typename B>
@@ -590,15 +561,15 @@ struct promote_storage_type;
template <typename A> template <typename A>
struct promote_storage_type<A, A> { struct promote_storage_type<A, A> {
typedef A ret; using ret = A;
}; };
template <typename A> template <typename A>
struct promote_storage_type<A, const A> { struct promote_storage_type<A, const A> {
typedef A ret; using ret = A;
}; };
template <typename A> template <typename A>
struct promote_storage_type<const A, A> { struct promote_storage_type<const A, A> {
typedef A ret; using ret = A;
}; };
/** \internal Specify the "storage kind" of applying a coefficient-wise /** \internal Specify the "storage kind" of applying a coefficient-wise
@@ -619,27 +590,27 @@ struct cwise_promote_storage_type;
template <typename A, typename Functor> template <typename A, typename Functor>
struct cwise_promote_storage_type<A, A, Functor> { struct cwise_promote_storage_type<A, A, Functor> {
typedef A ret; using ret = A;
}; };
template <typename Functor> template <typename Functor>
struct cwise_promote_storage_type<Dense, Dense, Functor> { struct cwise_promote_storage_type<Dense, Dense, Functor> {
typedef Dense ret; using ret = Dense;
}; };
template <typename A, typename Functor> template <typename A, typename Functor>
struct cwise_promote_storage_type<A, Dense, Functor> { struct cwise_promote_storage_type<A, Dense, Functor> {
typedef Dense ret; using ret = Dense;
}; };
template <typename B, typename Functor> template <typename B, typename Functor>
struct cwise_promote_storage_type<Dense, B, Functor> { struct cwise_promote_storage_type<Dense, B, Functor> {
typedef Dense ret; using ret = Dense;
}; };
template <typename Functor> template <typename Functor>
struct cwise_promote_storage_type<Sparse, Dense, Functor> { struct cwise_promote_storage_type<Sparse, Dense, Functor> {
typedef Sparse ret; using ret = Sparse;
}; };
template <typename Functor> template <typename Functor>
struct cwise_promote_storage_type<Dense, Sparse, Functor> { struct cwise_promote_storage_type<Dense, Sparse, Functor> {
typedef Sparse ret; using ret = Sparse;
}; };
template <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder> template <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder>
@@ -679,74 +650,74 @@ struct product_promote_storage_type;
template <typename A, int ProductTag> template <typename A, int ProductTag>
struct product_promote_storage_type<A, A, ProductTag> { struct product_promote_storage_type<A, A, ProductTag> {
typedef A ret; using ret = A;
}; };
template <int ProductTag> template <int ProductTag>
struct product_promote_storage_type<Dense, Dense, ProductTag> { struct product_promote_storage_type<Dense, Dense, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <typename A, int ProductTag> template <typename A, int ProductTag>
struct product_promote_storage_type<A, Dense, ProductTag> { struct product_promote_storage_type<A, Dense, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <typename B, int ProductTag> template <typename B, int ProductTag>
struct product_promote_storage_type<Dense, B, ProductTag> { struct product_promote_storage_type<Dense, B, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <typename A, int ProductTag> template <typename A, int ProductTag>
struct product_promote_storage_type<A, DiagonalShape, ProductTag> { struct product_promote_storage_type<A, DiagonalShape, ProductTag> {
typedef A ret; using ret = A;
}; };
template <typename B, int ProductTag> template <typename B, int ProductTag>
struct product_promote_storage_type<DiagonalShape, B, ProductTag> { struct product_promote_storage_type<DiagonalShape, B, ProductTag> {
typedef B ret; using ret = B;
}; };
template <int ProductTag> template <int ProductTag>
struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> { struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <int ProductTag> template <int ProductTag>
struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> { struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <typename A, int ProductTag> template <typename A, int ProductTag>
struct product_promote_storage_type<A, SkewSymmetricShape, ProductTag> { struct product_promote_storage_type<A, SkewSymmetricShape, ProductTag> {
typedef A ret; using ret = A;
}; };
template <typename B, int ProductTag> template <typename B, int ProductTag>
struct product_promote_storage_type<SkewSymmetricShape, B, ProductTag> { struct product_promote_storage_type<SkewSymmetricShape, B, ProductTag> {
typedef B ret; using ret = B;
}; };
template <int ProductTag> template <int ProductTag>
struct product_promote_storage_type<Dense, SkewSymmetricShape, ProductTag> { struct product_promote_storage_type<Dense, SkewSymmetricShape, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <int ProductTag> template <int ProductTag>
struct product_promote_storage_type<SkewSymmetricShape, Dense, ProductTag> { struct product_promote_storage_type<SkewSymmetricShape, Dense, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <int ProductTag> template <int ProductTag>
struct product_promote_storage_type<SkewSymmetricShape, SkewSymmetricShape, ProductTag> { struct product_promote_storage_type<SkewSymmetricShape, SkewSymmetricShape, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <typename A, int ProductTag> template <typename A, int ProductTag>
struct product_promote_storage_type<A, PermutationStorage, ProductTag> { struct product_promote_storage_type<A, PermutationStorage, ProductTag> {
typedef A ret; using ret = A;
}; };
template <typename B, int ProductTag> template <typename B, int ProductTag>
struct product_promote_storage_type<PermutationStorage, B, ProductTag> { struct product_promote_storage_type<PermutationStorage, B, ProductTag> {
typedef B ret; using ret = B;
}; };
template <int ProductTag> template <int ProductTag>
struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> { struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
template <int ProductTag> template <int ProductTag>
struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> { struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> {
typedef Dense ret; using ret = Dense;
}; };
/** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type. /** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type.
@@ -754,63 +725,56 @@ struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> {
*/ */
template <typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> template <typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
struct plain_row_type { struct plain_row_type {
typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime, using MatrixRowType =
int(ExpressionType::PlainObject::Options) | int(RowMajor), 1, ExpressionType::MaxColsAtCompileTime> Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime, int(ExpressionType::PlainObject::Options) | int(RowMajor), 1,
MatrixRowType; ExpressionType::MaxColsAtCompileTime>;
typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime, int(ExpressionType::PlainObject::Options) | int(RowMajor), using ArrayRowType =
1, ExpressionType::MaxColsAtCompileTime> Array<Scalar, 1, ExpressionType::ColsAtCompileTime, int(ExpressionType::PlainObject::Options) | int(RowMajor), 1,
ArrayRowType; ExpressionType::MaxColsAtCompileTime>;
typedef std::conditional_t<is_same<typename traits<ExpressionType>::XprKind, MatrixXpr>::value, MatrixRowType, using type = std::conditional_t<is_same<typename traits<ExpressionType>::XprKind, MatrixXpr>::value, MatrixRowType,
ArrayRowType> ArrayRowType>;
type;
}; };
template <typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> template <typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
struct plain_col_type { struct plain_col_type {
typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1, ExpressionType::PlainObject::Options & ~RowMajor, using MatrixColType =
ExpressionType::MaxRowsAtCompileTime, 1> Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1, ExpressionType::PlainObject::Options & ~RowMajor,
MatrixColType; ExpressionType::MaxRowsAtCompileTime, 1>;
typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1, ExpressionType::PlainObject::Options & ~RowMajor, using ArrayColType = Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
ExpressionType::MaxRowsAtCompileTime, 1> ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1>;
ArrayColType;
typedef std::conditional_t<is_same<typename traits<ExpressionType>::XprKind, MatrixXpr>::value, MatrixColType, using type = std::conditional_t<is_same<typename traits<ExpressionType>::XprKind, MatrixXpr>::value, MatrixColType,
ArrayColType> ArrayColType>;
type;
}; };
template <typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> template <typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
struct plain_diag_type { struct plain_diag_type {
enum { static constexpr int diag_size =
diag_size = internal::min_size_prefer_dynamic(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime), internal::min_size_prefer_dynamic(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime);
max_diag_size = min_size_prefer_fixed(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime) static constexpr int 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> using MatrixDiagType =
MatrixDiagType; Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1>;
typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType; using ArrayDiagType = Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1>;
typedef std::conditional_t<is_same<typename traits<ExpressionType>::XprKind, MatrixXpr>::value, MatrixDiagType, using type = std::conditional_t<is_same<typename traits<ExpressionType>::XprKind, MatrixXpr>::value, MatrixDiagType,
ArrayDiagType> ArrayDiagType>;
type;
}; };
template <typename Expr, typename Scalar = typename Expr::Scalar> template <typename Expr, typename Scalar = typename Expr::Scalar>
struct plain_constant_type { struct plain_constant_type {
enum { Options = (traits<Expr>::Flags & RowMajorBit) ? RowMajor : 0 }; static constexpr int Options = (traits<Expr>::Flags & RowMajorBit) ? RowMajor : 0;
typedef Array<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime, Options, using array_type = Array<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime, Options,
traits<Expr>::MaxRowsAtCompileTime, traits<Expr>::MaxColsAtCompileTime> traits<Expr>::MaxRowsAtCompileTime, traits<Expr>::MaxColsAtCompileTime>;
array_type;
typedef Matrix<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime, Options, using matrix_type = Matrix<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime, Options,
traits<Expr>::MaxRowsAtCompileTime, traits<Expr>::MaxColsAtCompileTime> traits<Expr>::MaxRowsAtCompileTime, traits<Expr>::MaxColsAtCompileTime>;
matrix_type;
typedef CwiseNullaryOp< using type = CwiseNullaryOp<
scalar_constant_op<Scalar>, scalar_constant_op<Scalar>,
const std::conditional_t<is_same<typename traits<Expr>::XprKind, MatrixXpr>::value, matrix_type, array_type>> const std::conditional_t<is_same<typename traits<Expr>::XprKind, MatrixXpr>::value, matrix_type, array_type>>;
type;
}; };
template <typename ExpressionType> template <typename ExpressionType>
@@ -852,7 +816,7 @@ template <typename S1, typename S2>
struct glue_shapes; struct glue_shapes;
template <> template <>
struct glue_shapes<DenseShape, TriangularShape> { struct glue_shapes<DenseShape, TriangularShape> {
typedef TriangularShape type; using type = TriangularShape;
}; };
template <typename T1, typename T2> template <typename T1, typename T2>
@@ -1047,34 +1011,34 @@ struct ScalarBinaryOpTraits
template <typename T, typename BinaryOp> template <typename T, typename BinaryOp>
struct ScalarBinaryOpTraits<T, T, BinaryOp> { struct ScalarBinaryOpTraits<T, T, BinaryOp> {
typedef T ReturnType; using ReturnType = T;
}; };
template <typename T, typename BinaryOp> template <typename T, typename BinaryOp>
struct ScalarBinaryOpTraits<T, typename NumTraits<std::enable_if_t<NumTraits<T>::IsComplex, T>>::Real, BinaryOp> { struct ScalarBinaryOpTraits<T, typename NumTraits<std::enable_if_t<NumTraits<T>::IsComplex, T>>::Real, BinaryOp> {
typedef T ReturnType; using ReturnType = T;
}; };
template <typename T, typename BinaryOp> template <typename T, typename BinaryOp>
struct ScalarBinaryOpTraits<typename NumTraits<std::enable_if_t<NumTraits<T>::IsComplex, T>>::Real, T, BinaryOp> { struct ScalarBinaryOpTraits<typename NumTraits<std::enable_if_t<NumTraits<T>::IsComplex, T>>::Real, T, BinaryOp> {
typedef T ReturnType; using ReturnType = T;
}; };
// For Matrix * Permutation // For Matrix * Permutation
template <typename T, typename BinaryOp> template <typename T, typename BinaryOp>
struct ScalarBinaryOpTraits<T, void, BinaryOp> { struct ScalarBinaryOpTraits<T, void, BinaryOp> {
typedef T ReturnType; using ReturnType = T;
}; };
// For Permutation * Matrix // For Permutation * Matrix
template <typename T, typename BinaryOp> template <typename T, typename BinaryOp>
struct ScalarBinaryOpTraits<void, T, BinaryOp> { struct ScalarBinaryOpTraits<void, T, BinaryOp> {
typedef T ReturnType; using ReturnType = T;
}; };
// for Permutation*Permutation // for Permutation*Permutation
template <typename BinaryOp> template <typename BinaryOp>
struct ScalarBinaryOpTraits<void, void, BinaryOp> { struct ScalarBinaryOpTraits<void, void, BinaryOp> {
typedef void ReturnType; using ReturnType = void;
}; };
// We require Lhs and Rhs to have "compatible" scalar types. // We require Lhs and Rhs to have "compatible" scalar types.