From ac732b0d1353a88268a044daa4e807331442115b Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Tue, 5 Sep 2017 23:49:34 +0200 Subject: [PATCH] Use _GLIBCXX_USE_CXX11_ABI for detecting gcc >= 5.0 --- docs/source/compilers.rst | 4 +++- include/xtensor/xutils.hpp | 45 ++------------------------------------ 2 files changed, 5 insertions(+), 44 deletions(-) diff --git a/docs/source/compilers.rst b/docs/source/compilers.rst index 8caadf97a..d9e1cfb7f 100644 --- a/docs/source/compilers.rst +++ b/docs/source/compilers.rst @@ -29,7 +29,9 @@ A consequence is that we need to use stack-allocated shape types in these cases. GCC < 5.1 and ``std::is_trivially_default_constructible`` --------------------------------------------------------- -The version of libstdc++ shipped with GCC older than 5.1 (and also used by Clang on linux) does not implement ``std::is_trivially_default_constructible`` but ``std::has_trivial_default_constructor`` instead. With GCC, this is done with a simple check of the version of GCC. In the case of the clang - linux combination, libstdc++ may be used. Since clang overrides the ``__GNUC__`` macro, the version of libstdc++ used cannot be retrived at runtime and some meta-programming techniques are used to determine which function is available. +The version of the STL shipped with versions of GCC older than 5.1 are missing a number of type traits, such as ``std::is_trivially_default_constructible``. However, for some of them, equivalent type traits with different names are provided, such as ``std::has_trivial_default_constructor``. + +In this case, we polyfill the proper standard names using the deprecated ``std::has_trivial_default_constructor``. This must also be done when the compiler is clang when it makes use of the GCC implementation of the STL, which is the default behavior on linux. Properly detecting the version of the GCC STL used by clang cannot be done with the ``__GNUC__`` macro, which are overridden by clang. Instead, we check for the definition of the macro ``_GLIBCXX_USE_CXX11_ABI`` which is only defined with GCC versions greater than 5. GCC-6 and the signature of ``std::isnan`` and ``std::isinf`` ------------------------------------------------------------ diff --git a/include/xtensor/xutils.hpp b/include/xtensor/xutils.hpp index b43fb7409..8180c96e3 100644 --- a/include/xtensor/xutils.hpp +++ b/include/xtensor/xutils.hpp @@ -987,58 +987,17 @@ namespace xt * xtrivial_default_construct implemenation * ********************************************/ -#if defined(__clang__) -#if !(defined(__APPLE__)) && !(defined(__EMSCRIPTEN__)) -// CLANG && LINUX -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -} -namespace std { template struct is_trivially_default_constructible; } -namespace std { template struct has_trivial_default_constructor; } -namespace xt -{ - - namespace detail - { - template - struct xtrivial_default_construct_impl; - - template - struct xtrivial_default_construct_impl : std::is_trivially_default_constructible {}; - - template - struct xtrivial_default_construct_impl : std::has_trivial_default_constructor {}; - } - - template - using xtrivially_default_constructible = detail::xtrivial_default_construct_impl>::value, T>; - -#pragma clang diagnostic pop -#else -// CLANG && ( APPLE || EMSCRIPTEN ) + #if !defined(__GNUG__) || defined(_LIBCPP_VERSION) || defined(_GLIBCXX_USE_CXX11_ABI) template using xtrivially_default_constructible = std::is_trivially_default_constructible; -#endif -#else -// NOT CLANG - #if defined(__GNUC__) && (__GNUC__ < 5 || (__GNUC__ == 5 && __GNUC_MINOR__ < 1)) - // OLD GCC - - template - using xtrivially_default_constructible = std::has_trivial_default_constructor; - #else template - using xtrivially_default_constructible = std::is_trivially_default_constructible; + using xtrivially_default_constructible = std::has_trivial_default_constructor; #endif - -#endif - } #endif