From 2468253c9adbb1e42be9227848c2d9a7b578dbaf Mon Sep 17 00:00:00 2001 From: Antonio Sanchez Date: Mon, 1 Mar 2021 15:57:22 -0800 Subject: Define EIGEN_CPLUSPLUS and replace most __cplusplus checks. The macro `__cplusplus` is not defined correctly in MSVC unless building with the the `/Zc:__cplusplus` flag. Instead, it defines `_MSVC_LANG` to the specified c++ standard version number. Here we introduce `EIGEN_CPLUSPLUS` which will contain the c++ version number both for MSVC and otherwise. This simplifies checks for supported features. Also replaced most instances of standard version checking via `__cplusplus` with the existing `EIGEN_COMP_CXXVER` macro for better clarity. Fixes: #2170 --- Eigen/src/Core/functors/StlFunctors.h | 4 +- Eigen/src/Core/util/Macros.h | 65 +++++++++++++--------- Eigen/src/Core/util/StaticAssert.h | 2 +- doc/examples/nullary_indexing.cpp | 2 +- test/main.h | 2 +- test/packetmath.cpp | 2 +- test/sparse_basic.cpp | 2 +- unsupported/Eigen/CXX11/ThreadPool | 2 +- .../Eigen/CXX11/src/util/CXX11Workarounds.h | 2 +- unsupported/test/special_packetmath.cpp | 2 +- 10 files changed, 50 insertions(+), 35 deletions(-) diff --git a/Eigen/src/Core/functors/StlFunctors.h b/Eigen/src/Core/functors/StlFunctors.h index 9c1d75850..d2e7b5b03 100644 --- a/Eigen/src/Core/functors/StlFunctors.h +++ b/Eigen/src/Core/functors/StlFunctors.h @@ -72,7 +72,7 @@ template struct functor_traits > { enum { Cost = 1, PacketAccess = false }; }; -#if (__cplusplus < 201103L) && (EIGEN_COMP_MSVC <= 1900) +#if (EIGEN_COMP_CXXVER < 11) // std::binder* are deprecated since c++11 and will be removed in c++17 template struct functor_traits > @@ -83,7 +83,7 @@ struct functor_traits > { enum { Cost = functor_traits::Cost, PacketAccess = false }; }; #endif -#if (__cplusplus < 201703L) && (EIGEN_COMP_MSVC < 1910) +#if (EIGEN_COMP_CXXVER < 17) // std::unary_negate is deprecated since c++17 and will be removed in c++20 template struct functor_traits > diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index 43890eab1..252d2be43 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -609,18 +609,36 @@ #define EIGEN_HAS_STATIC_ARRAY_TEMPLATE 0 #endif +// The macro EIGEN_CPLUSPLUS is a replacement for __cplusplus/_MSVC_LANG that +// works for both platforms, indicating the C++ standard version number. +// +// With MSVC, without defining /Zc:__cplusplus, the __cplusplus macro will +// report 199711L regardless of the language standard specified via /std. +// We need to rely on _MSVC_LANG instead, which is only available after +// VS2015.3. +#if EIGEN_COMP_MSVC_LANG > 0 +#define EIGEN_CPLUSPLUS EIGEN_COMP_MSVC_LANG +#elif EIGEN_COMP_MSVC >= 1900 +#define EIGEN_CPLUSPLUS 201103L +#elif defined(__cplusplus) +#define EIGEN_CPLUSPLUS __cplusplus +#else +#define EIGEN_CPLUSPLUS 0 +#endif // The macro EIGEN_COMP_CXXVER defines the c++ verson expected by the compiler. // For instance, if compiling with gcc and -std=c++17, then EIGEN_COMP_CXXVER // is defined to 17. -#if (defined(__cplusplus) && (__cplusplus > 201402L) || EIGEN_COMP_MSVC_LANG > 201402L) -#define EIGEN_COMP_CXXVER 17 -#elif (defined(__cplusplus) && (__cplusplus > 201103L) || EIGEN_COMP_MSVC >= 1910) -#define EIGEN_COMP_CXXVER 14 -#elif (defined(__cplusplus) && (__cplusplus >= 201103L) || EIGEN_COMP_MSVC >= 1900) -#define EIGEN_COMP_CXXVER 11 +#if EIGEN_CPLUSPLUS > 201703L + #define EIGEN_COMP_CXXVER 20 +#elif EIGEN_CPLUSPLUS > 201402L + #define EIGEN_COMP_CXXVER 17 +#elif EIGEN_CPLUSPLUS > 201103L + #define EIGEN_COMP_CXXVER 14 +#elif EIGEN_CPLUSPLUS >= 201103L + #define EIGEN_COMP_CXXVER 11 #else -#define EIGEN_COMP_CXXVER 03 + #define EIGEN_COMP_CXXVER 03 #endif @@ -645,8 +663,7 @@ #ifndef EIGEN_HAS_RVALUE_REFERENCES #if EIGEN_MAX_CPP_VER>=11 && \ (__has_feature(cxx_rvalue_references) || \ - (defined(__cplusplus) && __cplusplus >= 201103L) || \ - (EIGEN_COMP_MSVC >= 1600)) + (EIGEN_COMP_CXXVER >= 11) || (EIGEN_COMP_MSVC >= 1600)) #define EIGEN_HAS_RVALUE_REFERENCES 1 #else #define EIGEN_HAS_RVALUE_REFERENCES 0 @@ -731,12 +748,12 @@ // Does the compiler support variadic templates? #ifndef EIGEN_HAS_VARIADIC_TEMPLATES -#if EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) \ +#if EIGEN_MAX_CPP_VER>=11 && (EIGEN_COMP_CXXVER >= 11) \ && (!defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (EIGEN_COMP_NVCC >= 80000) ) // ^^ Disable the use of variadic templates when compiling with versions of nvcc older than 8.0 on ARM devices: // this prevents nvcc from crashing when compiling Eigen on Tegra X1 #define EIGEN_HAS_VARIADIC_TEMPLATES 1 -#elif EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) && defined(SYCL_DEVICE_ONLY) +#elif EIGEN_MAX_CPP_VER>=11 && (EIGEN_COMP_CXXVER >= 11) && defined(SYCL_DEVICE_ONLY) #define EIGEN_HAS_VARIADIC_TEMPLATES 1 #else #define EIGEN_HAS_VARIADIC_TEMPLATES 0 @@ -747,12 +764,12 @@ #ifndef EIGEN_HAS_CONSTEXPR #if defined(EIGEN_CUDACC) // Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above - #if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && (EIGEN_COMP_CLANG || EIGEN_COMP_NVCC >= 70500)) + #if EIGEN_MAX_CPP_VER>=14 && (EIGEN_COMP_CXXVER >= 11 && (EIGEN_COMP_CLANG || EIGEN_COMP_NVCC >= 70500)) #define EIGEN_HAS_CONSTEXPR 1 #endif - #elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (defined(__cplusplus) && __cplusplus >= 201402L) || \ - (EIGEN_GNUC_AT_LEAST(4,8) && (__cplusplus > 199711L)) || \ - (EIGEN_COMP_CLANG >= 306 && (__cplusplus > 199711L))) + #elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (EIGEN_COMP_CXXVER >= 14) || \ + (EIGEN_GNUC_AT_LEAST(4,8) && (EIGEN_COMP_CXXVER >= 11)) || \ + (EIGEN_COMP_CLANG >= 306 && (EIGEN_COMP_CXXVER >= 11))) #define EIGEN_HAS_CONSTEXPR 1 #endif @@ -771,7 +788,7 @@ // Does the compiler support C++11 math? // Let's be conservative and enable the default C++11 implementation only if we are sure it exists #ifndef EIGEN_HAS_CXX11_MATH - #if EIGEN_MAX_CPP_VER>=11 && ((__cplusplus > 201103L) || (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ + #if EIGEN_MAX_CPP_VER>=11 && ((EIGEN_COMP_CXXVER > 11) || (EIGEN_COMP_CXXVER == 11) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ && (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC)) #define EIGEN_HAS_CXX11_MATH 1 #else @@ -782,9 +799,8 @@ // Does the compiler support proper C++11 containers? #ifndef EIGEN_HAS_CXX11_CONTAINERS #if EIGEN_MAX_CPP_VER>=11 && \ - ((__cplusplus > 201103L) \ - || ((__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_ICC>=1400)) \ - || EIGEN_COMP_MSVC >= 1900) + ((EIGEN_COMP_CXXVER > 11) \ + || ((EIGEN_COMP_CXXVER == 11) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC>=1400))) #define EIGEN_HAS_CXX11_CONTAINERS 1 #else #define EIGEN_HAS_CXX11_CONTAINERS 0 @@ -795,9 +811,8 @@ #ifndef EIGEN_HAS_CXX11_NOEXCEPT #if EIGEN_MAX_CPP_VER>=11 && \ (__has_feature(cxx_noexcept) \ - || (__cplusplus > 201103L) \ - || ((__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_ICC>=1400)) \ - || EIGEN_COMP_MSVC >= 1900) + || (EIGEN_COMP_CXXVER > 11) \ + || ((EIGEN_COMP_CXXVER == 11) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC>=1400))) #define EIGEN_HAS_CXX11_NOEXCEPT 1 #else #define EIGEN_HAS_CXX11_NOEXCEPT 0 @@ -807,8 +822,8 @@ #ifndef EIGEN_HAS_CXX11_ATOMIC #if EIGEN_MAX_CPP_VER>=11 && \ (__has_feature(cxx_atomic) \ - || (__cplusplus > 201103L) \ - || ((__cplusplus >= 201103L) && (EIGEN_COMP_MSVC==0 || EIGEN_COMP_MSVC >= 1700))) + || (EIGEN_COMP_CXXVER > 11) \ + || ((EIGEN_COMP_CXXVER == 11) && (EIGEN_COMP_MSVC==0 || EIGEN_COMP_MSVC >= 1700))) #define EIGEN_HAS_CXX11_ATOMIC 1 #else #define EIGEN_HAS_CXX11_ATOMIC 0 @@ -817,7 +832,7 @@ #ifndef EIGEN_HAS_CXX11_OVERRIDE_FINAL #if EIGEN_MAX_CPP_VER>=11 && \ - (__cplusplus >= 201103L || EIGEN_COMP_MSVC >= 1700) + (EIGEN_COMP_CXXVER >= 11 || EIGEN_COMP_MSVC >= 1700) #define EIGEN_HAS_CXX11_OVERRIDE_FINAL 1 #else #define EIGEN_HAS_CXX11_OVERRIDE_FINAL 0 diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h index 2ef19a4dd..c45de5901 100644 --- a/Eigen/src/Core/util/StaticAssert.h +++ b/Eigen/src/Core/util/StaticAssert.h @@ -27,7 +27,7 @@ #ifndef EIGEN_STATIC_ASSERT #ifndef EIGEN_NO_STATIC_ASSERT - #if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600)) + #if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (EIGEN_COMP_CXXVER >= 11) || (EIGEN_COMP_MSVC >= 1600)) // if native static_assert is enabled, let's use it #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG); diff --git a/doc/examples/nullary_indexing.cpp b/doc/examples/nullary_indexing.cpp index ca1745628..b74db5fd1 100644 --- a/doc/examples/nullary_indexing.cpp +++ b/doc/examples/nullary_indexing.cpp @@ -56,7 +56,7 @@ int main() B = mat_indexing(A, ri+1, ci); std::cout << "A(ri+1,ci) =" << std::endl; std::cout << B << std::endl << std::endl; -#if __cplusplus >= 201103L +#if EIGEN_COMP_CXXVER >= 11 B = mat_indexing(A, ArrayXi::LinSpaced(13,0,12).unaryExpr([](int x){return x%4;}), ArrayXi::LinSpaced(4,0,3)); std::cout << "A(ArrayXi::LinSpaced(13,0,12).unaryExpr([](int x){return x%4;}), ArrayXi::LinSpaced(4,0,3)) =" << std::endl; std::cout << B << std::endl << std::endl; diff --git a/test/main.h b/test/main.h index 4f9887c81..cf061730f 100644 --- a/test/main.h +++ b/test/main.h @@ -45,7 +45,7 @@ #include #include #include -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) #include #include #ifdef EIGEN_USE_THREADS diff --git a/test/packetmath.cpp b/test/packetmath.cpp index 4ff193ee4..f5cce6436 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -761,7 +761,7 @@ void packetmath_real() { } } -#if EIGEN_HAS_C99_MATH && (__cplusplus > 199711L) +#if EIGEN_HAS_C99_MATH && (EIGEN_COMP_CXXVER >= 11) data1[0] = std::numeric_limits::infinity(); data1[1] = Scalar(-1); CHECK_CWISE1_IF(PacketTraits::HasLog1p, std::log1p, internal::plog1p); diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp index 17897fd61..f7ad930e9 100644 --- a/test/sparse_basic.cpp +++ b/test/sparse_basic.cpp @@ -413,7 +413,7 @@ template void sparse_basic(const SparseMatrixType& re m.setFromTriplets(triplets.begin(), triplets.end(), std::multiplies()); VERIFY_IS_APPROX(m, refMat_prod); -#if (defined(__cplusplus) && __cplusplus >= 201103L) +#if (EIGEN_COMP_CXXVER >= 11) m.setFromTriplets(triplets.begin(), triplets.end(), [] (Scalar,Scalar b) { return b; }); VERIFY_IS_APPROX(m, refMat_last); #endif diff --git a/unsupported/Eigen/CXX11/ThreadPool b/unsupported/Eigen/CXX11/ThreadPool index 5f59e9714..c5cafb2a1 100644 --- a/unsupported/Eigen/CXX11/ThreadPool +++ b/unsupported/Eigen/CXX11/ThreadPool @@ -30,7 +30,7 @@ // The code depends on CXX11, so only include the module if the // compiler supports it. -#if __cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900 +#if (EIGEN_COMP_CXXVER >= 11) #include #include #include diff --git a/unsupported/Eigen/CXX11/src/util/CXX11Workarounds.h b/unsupported/Eigen/CXX11/src/util/CXX11Workarounds.h index f1c0284ea..056736c39 100644 --- a/unsupported/Eigen/CXX11/src/util/CXX11Workarounds.h +++ b/unsupported/Eigen/CXX11/src/util/CXX11Workarounds.h @@ -32,7 +32,7 @@ * On the other hand, visual studio still doesn't claim to support C++11 although it's * compliant enugh for our purpose. */ -#if (__cplusplus <= 199711L) && (EIGEN_COMP_MSVC < 1900) +#if (EIGEN_COMP_CXXVER < 11) #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) #pragma GCC diagnostic error "-Wfatal-errors" #endif diff --git a/unsupported/test/special_packetmath.cpp b/unsupported/test/special_packetmath.cpp index 4f426eb8a..31233f1b0 100644 --- a/unsupported/test/special_packetmath.cpp +++ b/unsupported/test/special_packetmath.cpp @@ -114,7 +114,7 @@ template void packetmath_real() Scalar(std::pow(Scalar(10), internal::random(Scalar(-1),Scalar(2)))); } -#if EIGEN_HAS_C99_MATH && (__cplusplus > 199711L) +#if EIGEN_HAS_C99_MATH && (EIGEN_COMP_CXXVER >= 11) CHECK_CWISE1_IF(internal::packet_traits::HasLGamma, std::lgamma, internal::plgamma); CHECK_CWISE1_IF(internal::packet_traits::HasErf, std::erf, internal::perf); CHECK_CWISE1_IF(internal::packet_traits::HasErfc, std::erfc, internal::perfc); -- cgit v1.2.3