aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/CoreEvaluators.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2016-09-05 15:50:41 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2016-09-05 15:50:41 +0200
commite13071dd13233b5d07e725453617c40421cf7501 (patch)
tree45b6dd14f402e6c217e2a22116716805b6e8095b /Eigen/src/Core/CoreEvaluators.h
parentd123717e21d6b0d073b3bf7ef96eae7c0651b3b3 (diff)
Workaround a weird msvc 2012 compilation error.
Diffstat (limited to 'Eigen/src/Core/CoreEvaluators.h')
-rw-r--r--Eigen/src/Core/CoreEvaluators.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h
index 9b90543c3..a3fb253c0 100644
--- a/Eigen/src/Core/CoreEvaluators.h
+++ b/Eigen/src/Core/CoreEvaluators.h
@@ -393,6 +393,61 @@ struct nullary_wrapper<Scalar,NullaryOp,false,true,false>
template<typename Scalar,typename NullaryOp>
struct nullary_wrapper<Scalar,NullaryOp,false,false,false> {};
+#if EIGEN_COMP_MSVC>0 && EIGEN_COMP_MSVC<=1700
+
+// MSVC 2012 (and probably older ones too) exhibits a weird compilation error when
+// compiling:
+// Eigen::MatrixXf A = MatrixXf::Random(3,3);
+// Ref<const MatrixXf> R = 2.f*A;
+// and that has_*ary_operator<scalar_constant_op<float>> have not been instantiated yet.
+// The "problem" is that evaluator<2.f*A> is instantiated by traits<Ref>::match<2.f*A>
+// and at that time has_*ary_operator<T> returns true regardless of T.
+// Then nullary_wrapper is badly instantiated as nullary_wrapper<.,.,true,true,true>.
+// The trick is thus to defer the proper instantiation of nullary_wrapper when coeff(),
+// and packet() are really instantiated as implemented below:
+
+// This is a simple wrapper around Index to enforce the re-instantiation of
+// has_*ary_operator when needed.
+template<typename T> struct nullary_wrapper_workaround_msvc_2012 {
+ nullary_wrapper_workaround_msvc_2012(const T&);
+ operator T()const;
+};
+
+template<typename Scalar,typename NullaryOp>
+struct nullary_wrapper<Scalar,NullaryOp,true,true,true>
+{
+ template <typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i, IndexType j) const {
+ return nullary_wrapper<Scalar,NullaryOp,
+ has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value,
+ has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value,
+ has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value>().operator()(op,i,j);
+ }
+ template <typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i) const {
+ return nullary_wrapper<Scalar,NullaryOp,
+ has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value,
+ has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value,
+ has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value>().operator()(op,i);
+ }
+
+ template <typename T, typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i, IndexType j) const {
+ return nullary_wrapper<Scalar,NullaryOp,
+ has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value,
+ has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value,
+ has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value>().template packetOp<T>(op,i,j);
+ }
+ template <typename T, typename IndexType>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i) const {
+ return nullary_wrapper<Scalar,NullaryOp,
+ has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value,
+ has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value,
+ has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc_2012<IndexType> >::value>().template packetOp<T>(op,i);
+ }
+};
+#endif // MSVC<=2012 workaround
+
template<typename NullaryOp, typename PlainObjectType>
struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
: evaluator_base<CwiseNullaryOp<NullaryOp,PlainObjectType> >