diff options
author | Gael Guennebaud <g.gael@free.fr> | 2016-06-23 14:27:20 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2016-06-23 14:27:20 +0200 |
commit | 76faf4a9657efeed089aeedc98a769410c32d3d7 (patch) | |
tree | bbfe9d39d8e12ae5cd90ac8cbcb69a54ae81c953 /Eigen/src/Core/util/XprHelper.h | |
parent | 67c12531e567629e84713fbb3150560c916bd08c (diff) |
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)
Diffstat (limited to 'Eigen/src/Core/util/XprHelper.h')
-rw-r--r-- | Eigen/src/Core/util/XprHelper.h | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index c41c408b0..b372ac1ad 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -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 { |