mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Introduce a NumTraits<T>::Literal type to be used for literals, and
improve mixing type support in operations between arrays and scalars: - 2 * ArrayXcf is now optimized in the sense that the integer 2 is properly promoted to a float instead of a complex<float> (fix a regression) - 2.1 * ArrayXi is now forbiden (previously, 2.1 was converted to 2) - This mechanism should be applicable to any custom scalar type, assuming NumTraits<T>::Literal is properly defined (it defaults to T)
This commit is contained in:
@@ -906,35 +906,21 @@ namespace Eigen {
|
||||
const typename internal::plain_constant_type<EXPR,SCALAR>::type, const EXPR>
|
||||
|
||||
#define EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(METHOD,OPNAME) \
|
||||
EIGEN_DEVICE_FUNC inline \
|
||||
const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,Scalar,OPNAME) \
|
||||
(METHOD)(const Scalar& scalar) const { \
|
||||
return EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,Scalar,OPNAME)(derived(), \
|
||||
typename internal::plain_constant_type<Derived,Scalar>::type(derived().rows(), derived().cols(), scalar)); \
|
||||
} \
|
||||
\
|
||||
template <typename T> EIGEN_DEVICE_FUNC inline \
|
||||
typename internal::enable_if<ScalarBinaryOpTraits<Scalar,T,EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)<Scalar,T> >::Defined, \
|
||||
const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,T,OPNAME) >::type \
|
||||
const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename internal::promote_scalar_arg<Scalar EIGEN_COMMA T EIGEN_COMMA ScalarBinaryOpTraits<Scalar EIGEN_COMMA T EIGEN_COMMA EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)<Scalar EIGEN_COMMA T> >::Defined>::type,OPNAME) \
|
||||
(METHOD)(const T& scalar) const { \
|
||||
return EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,T,OPNAME)(derived(), \
|
||||
typename internal::plain_constant_type<Derived,T>::type(derived().rows(), derived().cols(), scalar)); \
|
||||
typedef typename internal::promote_scalar_arg<Scalar,T,ScalarBinaryOpTraits<Scalar,T,EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)<Scalar,T> >::Defined>::type PromotedT; \
|
||||
return EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,PromotedT,OPNAME)(derived(), \
|
||||
typename internal::plain_constant_type<Derived,PromotedT>::type(derived().rows(), derived().cols(), internal::scalar_constant_op<PromotedT>(scalar))); \
|
||||
}
|
||||
|
||||
#define EIGEN_MAKE_SCALAR_BINARY_OP_ONTHELEFT(METHOD,OPNAME) \
|
||||
EIGEN_DEVICE_FUNC inline friend \
|
||||
const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,Derived,OPNAME) \
|
||||
(METHOD)(const Scalar& scalar, const StorageBaseType& matrix) { \
|
||||
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,Derived,OPNAME)( \
|
||||
typename internal::plain_constant_type<Derived,Scalar>::type(matrix.derived().rows(), matrix.derived().cols(), scalar), matrix.derived()); \
|
||||
} \
|
||||
\
|
||||
template <typename T> EIGEN_DEVICE_FUNC inline friend \
|
||||
typename internal::enable_if<ScalarBinaryOpTraits<T,Scalar,EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)<T,Scalar> >::Defined, \
|
||||
const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(T,Derived,OPNAME) >::type \
|
||||
const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename internal::promote_scalar_arg<Scalar EIGEN_COMMA T EIGEN_COMMA ScalarBinaryOpTraits<T EIGEN_COMMA Scalar EIGEN_COMMA EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)<T EIGEN_COMMA Scalar> >::Defined>::type,Derived,OPNAME) \
|
||||
(METHOD)(const T& scalar, const StorageBaseType& matrix) { \
|
||||
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(T,Derived,OPNAME)( \
|
||||
typename internal::plain_constant_type<Derived,T>::type(matrix.derived().rows(), matrix.derived().cols(), scalar), matrix.derived()); \
|
||||
typedef typename internal::promote_scalar_arg<Scalar,T,ScalarBinaryOpTraits<T,Scalar,EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)<T,Scalar> >::Defined>::type PromotedT; \
|
||||
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(PromotedT,Derived,OPNAME)( \
|
||||
typename internal::plain_constant_type<Derived,PromotedT>::type(matrix.derived().rows(), matrix.derived().cols(), internal::scalar_constant_op<PromotedT>(scalar)), matrix.derived()); \
|
||||
}
|
||||
|
||||
#define EIGEN_MAKE_SCALAR_BINARY_OP(METHOD,OPNAME) \
|
||||
|
||||
@@ -45,6 +45,34 @@ inline IndexDest convert_index(const IndexSrc& idx) {
|
||||
}
|
||||
|
||||
|
||||
// promote_scalar_arg is an helper used in operation between an expression and a scalar, like:
|
||||
// expression * scalar
|
||||
// Its role is to determine how the type T of the scalar operand should be promoted given the scalar type ExprScalar of the given expression.
|
||||
// The IsSupported template parameter must be provided by the caller as: ScalarBinaryOpTraits<ExprScalar,T,op>::Defined using the proper order for ExprScalar and T.
|
||||
// Then the logic is as follows:
|
||||
// - if the operation is natively supported as defined by IsSupported, then the scalar type is not promoted, and T is returned.
|
||||
// - otherwise, NumTraits<T>::Literal is returned if T is implicitly convertible to NumTraits<T>::Literal AND that this does not imply a float to integer conversion.
|
||||
// - In all other cases, the promoted type is not defined, and the respective operation is thus invalid and not available (SFINAE).
|
||||
template<typename ExprScalar,typename T,
|
||||
bool IsSupported,
|
||||
bool ConvertibleToLiteral = internal::is_convertible<T,typename NumTraits<ExprScalar>::Literal>::value,
|
||||
bool IsSafe = NumTraits<T>::IsInteger || !NumTraits<typename NumTraits<ExprScalar>::Literal>::IsInteger>
|
||||
struct promote_scalar_arg
|
||||
{
|
||||
};
|
||||
|
||||
template<typename S,typename T, bool ConvertibleToLiteral, bool IsSafe>
|
||||
struct promote_scalar_arg<S,T,true,ConvertibleToLiteral,IsSafe>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename S,typename T>
|
||||
struct promote_scalar_arg<S,T,false,true,true>
|
||||
{
|
||||
typedef typename NumTraits<S>::Literal type;
|
||||
};
|
||||
|
||||
//classes inheriting no_assignment_operator don't generate a default operator=.
|
||||
class no_assignment_operator
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user