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
This commit is contained in:
Antonio Sanchez 2021-03-01 15:57:22 -08:00 committed by Rasmus Munk Larsen
parent 82d61af3a4
commit 2468253c9a
10 changed files with 50 additions and 35 deletions

View File

@ -72,7 +72,7 @@ template<typename T>
struct functor_traits<std::not_equal_to<T> >
{ 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<typename T>
struct functor_traits<std::binder2nd<T> >
@ -83,7 +83,7 @@ struct functor_traits<std::binder1st<T> >
{ enum { Cost = functor_traits<T>::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<typename T>
struct functor_traits<std::unary_negate<T> >

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -45,7 +45,7 @@
#include <queue>
#include <cassert>
#include <list>
#if __cplusplus >= 201103L
#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
#include <random>
#include <chrono>
#ifdef EIGEN_USE_THREADS

View File

@ -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<Scalar>::infinity();
data1[1] = Scalar(-1);
CHECK_CWISE1_IF(PacketTraits::HasLog1p, std::log1p, internal::plog1p);

View File

@ -413,7 +413,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
m.setFromTriplets(triplets.begin(), triplets.end(), std::multiplies<Scalar>());
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

View File

@ -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 <cstddef>
#include <cstring>
#include <time.h>

View File

@ -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

View File

@ -114,7 +114,7 @@ template<typename Scalar,typename Packet> void packetmath_real()
Scalar(std::pow(Scalar(10), internal::random<Scalar>(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<Scalar>::HasLGamma, std::lgamma, internal::plgamma);
CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasErf, std::erf, internal::perf);
CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasErfc, std::erfc, internal::perfc);