aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Core/CoreEvaluators.h34
-rw-r--r--Eigen/src/Core/Ref.h8
-rw-r--r--test/nullary.cpp15
3 files changed, 37 insertions, 20 deletions
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h
index c5ad37847..ece8c0fcf 100644
--- a/Eigen/src/Core/CoreEvaluators.h
+++ b/Eigen/src/Core/CoreEvaluators.h
@@ -393,9 +393,9 @@ 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
+#if EIGEN_COMP_MSVC>0
-// MSVC 2012 (and probably older ones too) exhibits a weird compilation error when
+// MSVC exhibits a weird compilation error when
// compiling:
// Eigen::MatrixXf A = MatrixXf::Random(3,3);
// Ref<const MatrixXf> R = 2.f*A;
@@ -408,8 +408,8 @@ struct nullary_wrapper<Scalar,NullaryOp,false,false,false> {};
// 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&);
+template<typename T> struct nullary_wrapper_workaround_msvc {
+ nullary_wrapper_workaround_msvc(const T&);
operator T()const;
};
@@ -419,34 +419,34 @@ 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);
+ has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
+ has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
+ has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<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);
+ has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
+ has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
+ has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<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);
+ has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
+ has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
+ has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<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);
+ has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
+ has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
+ has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().template packetOp<T>(op,i);
}
};
-#endif // MSVC<=2012 workaround
+#endif // MSVC workaround
template<typename NullaryOp, typename PlainObjectType>
struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
diff --git a/Eigen/src/Core/Ref.h b/Eigen/src/Core/Ref.h
index 17065fdd5..bdf24f52a 100644
--- a/Eigen/src/Core/Ref.h
+++ b/Eigen/src/Core/Ref.h
@@ -35,7 +35,13 @@ struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
|| (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
OuterStrideMatch = Derived::IsVectorAtCompileTime
|| int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
- AlignmentMatch = (int(traits<PlainObjectType>::Alignment)==int(Unaligned)) || (int(evaluator<Derived>::Alignment) >= int(Alignment)), // FIXME the first condition is not very clear, it should be replaced by the required alignment
+ // NOTE, this indirection of evaluator<Derived>::Alignment is needed
+ // to workaround a very strange bug in MSVC related to the instantiation
+ // of has_*ary_operator in evaluator<CwiseNullaryOp>.
+ // This line is surprisingly very sensitive. For instance, simply adding parenthesis
+ // as "DerivedAlignment = (int(evaluator<Derived>::Alignment))," will make MSVC fail...
+ DerivedAlignment = int(evaluator<Derived>::Alignment),
+ AlignmentMatch = (int(traits<PlainObjectType>::Alignment)==int(Unaligned)) || (DerivedAlignment >= int(Alignment)), // FIXME the first condition is not very clear, it should be replaced by the required alignment
ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
};
diff --git a/test/nullary.cpp b/test/nullary.cpp
index a3c8b991e..9063c6de8 100644
--- a/test/nullary.cpp
+++ b/test/nullary.cpp
@@ -171,8 +171,9 @@ void test_nullary()
VERIFY(( !internal::has_binary_operator<internal::linspaced_op<float,float,false> >::value ));
VERIFY(( internal::functor_has_linear_access<internal::linspaced_op<float,float,false> >::ret ));
- // Regression unit test for a weird MSVC 2012 bug.
- // Search "nullary_wrapper_workaround_msvc_2012" in CoreEvaluators.h for the details.
+ // Regression unit test for a weird MSVC bug.
+ // Search "nullary_wrapper_workaround_msvc" in CoreEvaluators.h for the details.
+ // See also traits<Ref>::match.
{
MatrixXf A = MatrixXf::Random(3,3);
Ref<const MatrixXf> R = 2.0*A;
@@ -183,6 +184,16 @@ void test_nullary()
VectorXi V = VectorXi::Random(3);
Ref<const VectorXi> R2 = VectorXi::LinSpaced(3,1,3)+V;
VERIFY_IS_APPROX(R2, V+Vector3i(1,2,3));
+
+ VERIFY(( internal::has_nullary_operator<internal::scalar_constant_op<float> >::value ));
+ VERIFY(( !internal::has_unary_operator<internal::scalar_constant_op<float> >::value ));
+ VERIFY(( !internal::has_binary_operator<internal::scalar_constant_op<float> >::value ));
+ VERIFY(( internal::functor_has_linear_access<internal::scalar_constant_op<float> >::ret ));
+
+ VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<int,int,false> >::value ));
+ VERIFY(( internal::has_unary_operator<internal::linspaced_op<int,int,false> >::value ));
+ VERIFY(( !internal::has_binary_operator<internal::linspaced_op<int,int,false> >::value ));
+ VERIFY(( internal::functor_has_linear_access<internal::linspaced_op<int,int,false> >::ret ));
}
#endif
}