aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2015-10-28 16:27:20 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2015-10-28 16:27:20 +0100
commit28ddb5158dbe2a633a11f77ad7145ceae08abbf3 (patch)
tree277014431723c270d827294386a99b359fe7a4af
parent1a842c0dc441cca1bd66a516b16d7fe6a4c0ba26 (diff)
Enable std::isfinite/nan/inf on MSVC 2013 and newer and clang. Fix isinf for gcc4.4 and older msvc with fast-math.
-rw-r--r--Eigen/src/Core/MathFunctions.h42
-rw-r--r--test/fastmath.cpp8
2 files changed, 26 insertions, 24 deletions
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index 6d2730960..515eca137 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -818,8 +818,8 @@ inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
}
-// std::is* do not work with fast-math and gcc
-#if EIGEN_HAS_CXX11_MATH && !(EIGEN_COMP_GNUC_STRICT && __FINITE_MATH_ONLY__)
+// std::is* do not work with fast-math and gcc, std::is* are available on MSVC 2013 and newer, as well as in clang.
+#if (EIGEN_HAS_CXX11_MATH && !(EIGEN_COMP_GNUC_STRICT && __FINITE_MATH_ONLY__)) || (EIGEN_COMP_MSVC>=1800) || (EIGEN_COMP_CLANG)
#define EIGEN_USE_STD_FPCLASSIFY 1
#else
#define EIGEN_USE_STD_FPCLASSIFY 0
@@ -865,40 +865,34 @@ bool (isnan)(const T& x)
#if EIGEN_COMP_MSVC
+template<typename T> EIGEN_DEVICE_FUNC bool isinf_msvc_helper(T x)
+{
+ return _fpclass(x)==_FPCLASS_NINF || _fpclass(x)==_FPCLASS_PINF;
+}
+
//MSVC defines a _isnan builtin function, but for double only
-template<> EIGEN_DEVICE_FUNC bool (isnan)(const long double& x) { return _isnan(double(x)); }
+template<> EIGEN_DEVICE_FUNC bool (isnan)(const long double& x) { return _isnan(x); }
template<> EIGEN_DEVICE_FUNC bool (isnan)(const double& x) { return _isnan(x); }
-template<> EIGEN_DEVICE_FUNC bool (isnan)(const float& x) { return _isnan(double(x)); }
+template<> EIGEN_DEVICE_FUNC bool (isnan)(const float& x) { return _isnan(x); }
-#elif (defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__)
+template<> EIGEN_DEVICE_FUNC bool (isnan)(const long double& x) { return isinf_msvc_helper(x); }
+template<> EIGEN_DEVICE_FUNC bool (isnan)(const double& x) { return isinf_msvc_helper(x); }
+template<> EIGEN_DEVICE_FUNC bool (isnan)(const float& x) { return isinf_msvc_helper(x); }
-#if EIGEN_COMP_CLANG
- #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC __attribute__((optnone))
-#elif EIGEN_COMP_GNUC
- #if EIGEN_GNUC_AT_LEAST(5,0)
- #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC __attribute__((optimize("no-finite-math-only")))
- #else
- #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC __attribute__((noinline,optimize("no-finite-math-only")))
- #endif
+#elif (defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ && EIGEN_COMP_GNUC)
+
+#if EIGEN_GNUC_AT_LEAST(5,0)
+ #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC __attribute__((optimize("no-finite-math-only")))
#else
- #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC
+ #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC __attribute__((noinline,optimize("no-finite-math-only")))
#endif
-template<typename T>
-EIGEN_TMP_NOOPT_ATTRIB
-bool isinf_helper(const T& x)
-{
- return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
-}
-
template<> EIGEN_TMP_NOOPT_ATTRIB bool (isnan)(const long double& x) { return __builtin_isnan(x); }
template<> EIGEN_TMP_NOOPT_ATTRIB bool (isnan)(const double& x) { return __builtin_isnan(x); }
template<> EIGEN_TMP_NOOPT_ATTRIB bool (isnan)(const float& x) { return __builtin_isnan(x); }
template<> EIGEN_TMP_NOOPT_ATTRIB bool (isinf)(const double& x) { return __builtin_isinf(x); }
template<> EIGEN_TMP_NOOPT_ATTRIB bool (isinf)(const float& x) { return __builtin_isinf(x); }
-#if EIGEN_COMP_CLANG
-template<> EIGEN_TMP_NOOPT_ATTRIB bool (isinf)(const long double& x) { return __builtin_isinf(double(x)); }
-#endif
+template<> EIGEN_TMP_NOOPT_ATTRIB bool (isinf)(const long double& x) { return __builtin_isinf(x); }
#undef EIGEN_TMP_NOOPT_ATTRIB
diff --git a/test/fastmath.cpp b/test/fastmath.cpp
index 2911c0544..16462d54f 100644
--- a/test/fastmath.cpp
+++ b/test/fastmath.cpp
@@ -18,6 +18,14 @@ void check(bool b, bool ref)
std::cout << " BAD ";
}
+#if EIGEN_COMP_MSVC < 1800
+namespace std {
+ template<typename T> bool (isfinite)(T x) { return _finite(x); }
+ template<typename T> bool (isnan)(T x) { return _isnan(x); }
+ template<typename T> bool (isinf)(T x) { return _fpclass(x)==_FPCLASS_NINF || _fpclass(x)==_FPCLASS_PINF; }
+}
+#endif
+
template<typename T>
void check_inf_nan(bool dryrun) {
Matrix<T,Dynamic,1> m(10);