11 #ifndef EIGEN_XPRHELPER_H
12 #define EIGEN_XPRHELPER_H
17 #if EIGEN_COMP_GNUC && !EIGEN_GNUC_AT(4,3)
18 #define EIGEN_EMPTY_STRUCT_CTOR(X) \
19 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
20 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {}
22 #define EIGEN_EMPTY_STRUCT_CTOR(X)
29 template<
typename IndexDest,
typename IndexSrc>
31 inline IndexDest convert_index(
const IndexSrc& idx) {
33 eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() &&
"Index value to big for target type");
34 return IndexDest(idx);
47 template<
typename ExprScalar,
typename T,
bool IsSupported>
48 struct promote_scalar_arg;
50 template<
typename S,
typename T>
51 struct promote_scalar_arg<S,T,true>
57 template<
typename ExprScalar,
typename T,
typename PromotedType,
58 bool ConvertibleToLiteral = internal::is_convertible<T,PromotedType>::value,
59 bool IsSafe = NumTraits<T>::IsInteger || !NumTraits<PromotedType>::IsInteger>
60 struct promote_scalar_arg_unsupported;
63 template<
typename S,
typename T>
64 struct promote_scalar_arg<S,T,false> : promote_scalar_arg_unsupported<S,T,typename NumTraits<S>::Literal> {};
67 template<
typename S,
typename T,
typename PromotedType>
68 struct promote_scalar_arg_unsupported<S,T,PromotedType,true,true>
70 typedef PromotedType type;
75 template<
typename ExprScalar,
typename T,
typename PromotedType>
76 struct promote_scalar_arg_unsupported<ExprScalar,T,PromotedType,false,true>
77 : promote_scalar_arg_unsupported<ExprScalar,T,ExprScalar>
81 template<
typename S,
typename T,
typename PromotedType,
bool ConvertibleToLiteral>
82 struct promote_scalar_arg_unsupported<S,T,PromotedType,ConvertibleToLiteral,false> {};
85 template<
typename S,
typename T>
86 struct promote_scalar_arg_unsupported<S,T,S,false,true> {};
89 class no_assignment_operator
92 no_assignment_operator& operator=(
const no_assignment_operator&);
94 EIGEN_DEFAULT_COPY_CONSTRUCTOR(no_assignment_operator)
95 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(no_assignment_operator)
99 template<
typename I1,
typename I2>
100 struct promote_index_type
102 typedef typename conditional<(
sizeof(I1)<
sizeof(I2)), I2, I1>::type type;
109 template<
typename T,
int Value>
class variable_if_dynamic
112 EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
113 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
114 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE T value() {
return T(Value); }
115 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void setValue(T) {}
118 template<
typename T>
class variable_if_dynamic<T,
Dynamic>
121 EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(
false); }
123 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit variable_if_dynamic(T value) : m_value(value) {}
124 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value()
const {
return m_value; }
125 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void setValue(T value) { m_value = value; }
130 template<
typename T,
int Value>
class variable_if_dynamicindex
133 EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
134 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
135 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE T value() {
return T(Value); }
136 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void setValue(T) {}
139 template<
typename T>
class variable_if_dynamicindex<T,
DynamicIndex>
142 EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(
false); }
144 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit variable_if_dynamicindex(T value) : m_value(value) {}
145 EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value()
const {
return m_value; }
146 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void setValue(T value) { m_value = value; }
149 template<
typename T>
struct functor_traits
154 PacketAccess =
false,
159 template<
typename T>
struct packet_traits;
161 template<
typename T>
struct unpacket_traits
172 template<
int Size,
typename PacketType,
173 bool Stop = Size==
Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,
typename unpacket_traits<PacketType>::half>::value>
174 struct find_best_packet_helper;
176 template<
int Size,
typename PacketType>
177 struct find_best_packet_helper<Size,PacketType,true>
179 typedef PacketType type;
182 template<
int Size,
typename PacketType>
183 struct find_best_packet_helper<Size,PacketType,false>
185 typedef typename find_best_packet_helper<Size,typename unpacket_traits<PacketType>::half>::type type;
188 template<
typename T,
int Size>
189 struct find_best_packet
191 typedef typename find_best_packet_helper<Size,typename packet_traits<T>::type>::type type;
194 #if EIGEN_MAX_STATIC_ALIGN_BYTES>0
195 template<
int ArrayBytes,
int AlignmentBytes,
196 bool Match = bool((ArrayBytes%AlignmentBytes)==0),
197 bool TryHalf = bool(EIGEN_MIN_ALIGN_BYTES<AlignmentBytes) >
198 struct compute_default_alignment_helper
203 template<
int ArrayBytes,
int AlignmentBytes,
bool TryHalf>
204 struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf>
206 enum { value = AlignmentBytes };
209 template<
int ArrayBytes,
int AlignmentBytes>
210 struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true>
213 enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
218 template<
int ArrayBytes,
int AlignmentBytes>
219 struct compute_default_alignment_helper
225 template<
typename T,
int Size>
struct compute_default_alignment {
226 enum { value = compute_default_alignment_helper<Size*
sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value };
229 template<
typename T>
struct compute_default_alignment<T,
Dynamic> {
230 enum { value = EIGEN_MAX_ALIGN_BYTES };
233 template<
typename _Scalar,
int _Rows,
int _Cols,
237 : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
238 int _MaxRows = _Rows,
240 >
class make_proper_matrix_type
243 IsColVector = _Cols==1 && _Rows!=1,
244 IsRowVector = _Rows==1 && _Cols!=1,
250 typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type;
253 template<
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
int MaxCols>
254 class compute_matrix_flags
264 template<
int _Rows,
int _Cols>
struct size_at_compile_time
269 template<
typename XprType>
struct size_of_xpr_at_compile_time
271 enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret };
278 template<typename T, typename StorageKind = typename traits<T>::StorageKind>
struct plain_matrix_type;
279 template<
typename T,
typename BaseClassType,
int Flags>
struct plain_matrix_type_dense;
280 template<
typename T>
struct plain_matrix_type<T,Dense>
282 typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, traits<T>::Flags>::type type;
284 template<
typename T>
struct plain_matrix_type<T,DiagonalShape>
286 typedef typename T::PlainObject type;
289 template<
typename T,
int Flags>
struct plain_matrix_type_dense<T,MatrixXpr,Flags>
291 typedef Matrix<typename traits<T>::Scalar,
292 traits<T>::RowsAtCompileTime,
293 traits<T>::ColsAtCompileTime,
295 traits<T>::MaxRowsAtCompileTime,
296 traits<T>::MaxColsAtCompileTime
300 template<
typename T,
int Flags>
struct plain_matrix_type_dense<T,ArrayXpr,Flags>
302 typedef Array<typename traits<T>::Scalar,
303 traits<T>::RowsAtCompileTime,
304 traits<T>::ColsAtCompileTime,
306 traits<T>::MaxRowsAtCompileTime,
307 traits<T>::MaxColsAtCompileTime
315 template<typename T, typename StorageKind = typename traits<T>::StorageKind>
struct eval;
317 template<
typename T>
struct eval<T,Dense>
319 typedef typename plain_matrix_type<T>::type type;
330 template<
typename T>
struct eval<T,DiagonalShape>
332 typedef typename plain_matrix_type<T>::type type;
336 template<
typename _Scalar,
int _Rows,
int _Cols,
int _Options,
int _MaxRows,
int _MaxCols>
337 struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
339 typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
342 template<
typename _Scalar,
int _Rows,
int _Cols,
int _Options,
int _MaxRows,
int _MaxCols>
343 struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
345 typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
350 template<typename T, typename StorageKind = typename traits<T>::StorageKind>
struct plain_object_eval;
353 struct plain_object_eval<T,Dense>
355 typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, evaluator<T>::Flags>::type type;
361 template<
typename T>
struct plain_matrix_type_column_major
363 enum { Rows = traits<T>::RowsAtCompileTime,
364 Cols = traits<T>::ColsAtCompileTime,
365 MaxRows = traits<T>::MaxRowsAtCompileTime,
366 MaxCols = traits<T>::MaxColsAtCompileTime
368 typedef Matrix<typename traits<T>::Scalar,
379 template<
typename T>
struct plain_matrix_type_row_major
381 enum { Rows = traits<T>::RowsAtCompileTime,
382 Cols = traits<T>::ColsAtCompileTime,
383 MaxRows = traits<T>::MaxRowsAtCompileTime,
384 MaxCols = traits<T>::MaxColsAtCompileTime
386 typedef Matrix<typename traits<T>::Scalar,
398 template <
typename T>
401 typedef typename conditional<
402 bool(traits<T>::Flags & NestByRefBit),
407 typedef typename conditional<
408 bool(traits<T>::Flags & NestByRefBit),
411 >::type non_const_type;
415 template<
typename T1,
typename T2>
416 struct transfer_constness
418 typedef typename conditional<
419 bool(internal::is_const<T1>::value),
420 typename internal::add_const_on_value_type<T2>::type,
440 template<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type>
struct nested_eval
443 ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
444 CoeffReadCost = evaluator<T>::CoeffReadCost,
450 CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
451 CostNoEval = NAsInteger * CoeffReadCost,
452 Evaluate = (
int(evaluator<T>::Flags) &
EvalBeforeNestingBit) || (
int(CostEval) < int(CostNoEval))
455 typedef typename conditional<Evaluate, PlainObject, typename ref_selector<T>::type>::type type;
460 inline T* const_cast_ptr(
const T* ptr)
462 return const_cast<T*
>(ptr);
465 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
466 struct dense_xpr_base
471 template<
typename Derived>
472 struct dense_xpr_base<Derived, MatrixXpr>
474 typedef MatrixBase<Derived> type;
477 template<
typename Derived>
478 struct dense_xpr_base<Derived, ArrayXpr>
480 typedef ArrayBase<Derived> type;
483 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind,
typename StorageKind =
typename traits<Derived>::StorageKind>
484 struct generic_xpr_base;
486 template<
typename Derived,
typename XprKind>
487 struct generic_xpr_base<Derived, XprKind, Dense>
489 typedef typename dense_xpr_base<Derived,XprKind>::type type;
492 template<
typename XprType,
typename CastType>
struct cast_return_type
494 typedef typename XprType::Scalar CurrentScalarType;
495 typedef typename remove_all<CastType>::type _CastType;
496 typedef typename _CastType::Scalar NewScalarType;
497 typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value,
498 const XprType&,CastType>::type type;
501 template <
typename A,
typename B>
struct promote_storage_type;
503 template <
typename A>
struct promote_storage_type<A,A>
507 template <
typename A>
struct promote_storage_type<A, const A>
511 template <
typename A>
struct promote_storage_type<const A, A>
529 template <
typename A,
typename B,
typename Functor>
struct cwise_promote_storage_type;
531 template <
typename A,
typename Functor>
struct cwise_promote_storage_type<A,A,Functor> {
typedef A ret; };
532 template <
typename Functor>
struct cwise_promote_storage_type<Dense,Dense,Functor> {
typedef Dense ret; };
533 template <
typename A,
typename Functor>
struct cwise_promote_storage_type<A,Dense,Functor> {
typedef Dense ret; };
534 template <
typename B,
typename Functor>
struct cwise_promote_storage_type<Dense,B,Functor> {
typedef Dense ret; };
535 template <
typename Functor>
struct cwise_promote_storage_type<Sparse,Dense,Functor> {
typedef Sparse ret; };
536 template <
typename Functor>
struct cwise_promote_storage_type<Dense,Sparse,Functor> {
typedef Sparse ret; };
538 template <
typename LhsKind,
typename RhsKind,
int LhsOrder,
int RhsOrder>
struct cwise_promote_storage_order {
539 enum { value = LhsOrder };
542 template <
typename LhsKind,
int LhsOrder,
int RhsOrder>
struct cwise_promote_storage_order<LhsKind,Sparse,LhsOrder,RhsOrder> {
enum { value = RhsOrder }; };
543 template <
typename RhsKind,
int LhsOrder,
int RhsOrder>
struct cwise_promote_storage_order<Sparse,RhsKind,LhsOrder,RhsOrder> {
enum { value = LhsOrder }; };
544 template <
int Order>
struct cwise_promote_storage_order<Sparse,Sparse,Order,Order> {
enum { value = Order }; };
561 template <
typename A,
typename B,
int ProductTag>
struct product_promote_storage_type;
563 template <
typename A,
int ProductTag>
struct product_promote_storage_type<A, A, ProductTag> {
typedef A ret;};
564 template <
int ProductTag>
struct product_promote_storage_type<Dense, Dense, ProductTag> {
typedef Dense ret;};
565 template <
typename A,
int ProductTag>
struct product_promote_storage_type<A, Dense, ProductTag> {
typedef Dense ret; };
566 template <
typename B,
int ProductTag>
struct product_promote_storage_type<Dense, B, ProductTag> {
typedef Dense ret; };
568 template <
typename A,
int ProductTag>
struct product_promote_storage_type<A, DiagonalShape, ProductTag> {
typedef A ret; };
569 template <
typename B,
int ProductTag>
struct product_promote_storage_type<DiagonalShape, B, ProductTag> {
typedef B ret; };
570 template <
int ProductTag>
struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> {
typedef Dense ret; };
571 template <
int ProductTag>
struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> {
typedef Dense ret; };
573 template <
typename A,
int ProductTag>
struct product_promote_storage_type<A, PermutationStorage, ProductTag> {
typedef A ret; };
574 template <
typename B,
int ProductTag>
struct product_promote_storage_type<PermutationStorage, B, ProductTag> {
typedef B ret; };
575 template <
int ProductTag>
struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> {
typedef Dense ret; };
576 template <
int ProductTag>
struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> {
typedef Dense ret; };
581 template<
typename ExpressionType,
typename Scalar =
typename ExpressionType::Scalar>
582 struct plain_row_type
584 typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
585 ExpressionType::PlainObject::Options |
RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
586 typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
587 ExpressionType::PlainObject::Options |
RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
589 typedef typename conditional<
590 is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
596 template<
typename ExpressionType,
typename Scalar =
typename ExpressionType::Scalar>
597 struct plain_col_type
599 typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
600 ExpressionType::PlainObject::Options & ~
RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
601 typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
602 ExpressionType::PlainObject::Options & ~
RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
604 typedef typename conditional<
605 is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
611 template<
typename ExpressionType,
typename Scalar =
typename ExpressionType::Scalar>
612 struct plain_diag_type
614 enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
615 max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
617 typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType;
618 typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType;
620 typedef typename conditional<
621 is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
627 template<
typename Expr,
typename Scalar =
typename Expr::Scalar>
628 struct plain_constant_type
633 Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> array_type;
636 Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> matrix_type;
638 typedef CwiseNullaryOp<scalar_constant_op<Scalar>,
const typename conditional<is_same< typename traits<Expr>::XprKind, MatrixXpr >::value, matrix_type, array_type>::type > type;
641 template<
typename ExpressionType>
644 enum { value = (!bool(is_const<ExpressionType>::value)) &&
645 bool(traits<ExpressionType>::Flags &
LvalueBit) };
648 template<
typename T>
struct is_diagonal
649 {
enum { ret =
false }; };
651 template<
typename T>
struct is_diagonal<DiagonalBase<T> >
652 {
enum { ret =
true }; };
654 template<
typename T>
struct is_diagonal<DiagonalWrapper<T> >
655 {
enum { ret =
true }; };
657 template<
typename T,
int S>
struct is_diagonal<DiagonalMatrix<T,S> >
658 {
enum { ret =
true }; };
660 template<
typename S1,
typename S2>
struct glue_shapes;
661 template<>
struct glue_shapes<DenseShape,TriangularShape> {
typedef TriangularShape type; };
663 template<
typename T1,
typename T2>
664 bool is_same_dense(
const T1 &mat1,
const T2 &mat2,
typename enable_if<has_direct_access<T1>::ret&&has_direct_access<T2>::ret, T1>::type * = 0)
666 return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
669 template<
typename T1,
typename T2>
670 bool is_same_dense(
const T1 &,
const T2 &,
typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0)
677 template<
typename T,
bool Vectorized=false,
typename EnaleIf =
void>
678 struct scalar_div_cost {
679 enum { value = 8*NumTraits<T>::MulCost };
682 template<
typename T,
bool Vectorized>
683 struct scalar_div_cost<std::complex<T>, Vectorized> {
684 enum { value = 2*scalar_div_cost<T>::value
685 + 6*NumTraits<T>::MulCost
686 + 3*NumTraits<T>::AddCost
691 template<
bool Vectorized>
692 struct scalar_div_cost<signed long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> {
enum { value = 24 }; };
693 template<
bool Vectorized>
694 struct scalar_div_cost<unsigned long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> {
enum { value = 21 }; };
697 #ifdef EIGEN_DEBUG_ASSIGN
698 std::string demangle_traversal(
int t)
700 if(t==DefaultTraversal)
return "DefaultTraversal";
701 if(t==LinearTraversal)
return "LinearTraversal";
702 if(t==InnerVectorizedTraversal)
return "InnerVectorizedTraversal";
703 if(t==LinearVectorizedTraversal)
return "LinearVectorizedTraversal";
704 if(t==SliceVectorizedTraversal)
return "SliceVectorizedTraversal";
707 std::string demangle_unrolling(
int t)
709 if(t==NoUnrolling)
return "NoUnrolling";
710 if(t==InnerUnrolling)
return "InnerUnrolling";
711 if(t==CompleteUnrolling)
return "CompleteUnrolling";
714 std::string demangle_flags(
int f)
722 if(f&NestByRefBit) res +=
" | NestByRef";
768 template<
typename ScalarA,
typename ScalarB,
typename BinaryOp=
internal::scalar_product_op<ScalarA,ScalarB> >
770 #ifndef EIGEN_PARSED_BY_DOXYGEN
772 : internal::scalar_product_traits<ScalarA,ScalarB>
773 #endif // EIGEN_PARSED_BY_DOXYGEN
776 template<
typename T,
typename BinaryOp>
779 typedef T ReturnType;
782 template <
typename T,
typename BinaryOp>
783 struct ScalarBinaryOpTraits<T, typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, BinaryOp>
785 typedef T ReturnType;
787 template <
typename T,
typename BinaryOp>
788 struct ScalarBinaryOpTraits<typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, T, BinaryOp>
790 typedef T ReturnType;
794 template<
typename T,
typename BinaryOp>
795 struct ScalarBinaryOpTraits<T,void,BinaryOp>
797 typedef T ReturnType;
801 template<
typename T,
typename BinaryOp>
802 struct ScalarBinaryOpTraits<void,T,BinaryOp>
804 typedef T ReturnType;
808 template<
typename BinaryOp>
809 struct ScalarBinaryOpTraits<void,void,BinaryOp>
811 typedef void ReturnType;
818 #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
819 EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
820 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
824 #endif // EIGEN_XPRHELPER_H