Skip to content

Commit

Permalink
Merge pull request #396 from SylvainCorlay/clang-libstdcpp
Browse files Browse the repository at this point in the history
Use _GLIBCXX_USE_CXX11_ABI for detecting gcc >= 5.0
  • Loading branch information
SylvainCorlay committed Sep 5, 2017
2 parents 7d73b0a + ac732b0 commit a8d6ffb
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 44 deletions.
4 changes: 3 additions & 1 deletion docs/source/compilers.rst
Expand Up @@ -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``
------------------------------------------------------------
Expand Down
45 changes: 2 additions & 43 deletions include/xtensor/xutils.hpp
Expand Up @@ -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 <class T> struct is_trivially_default_constructible; }
namespace std { template <class T> struct has_trivial_default_constructor; }
namespace xt
{

namespace detail
{
template <bool C, class T>
struct xtrivial_default_construct_impl;

template <class T>
struct xtrivial_default_construct_impl<true, T> : std::is_trivially_default_constructible<T> {};

template <class T>
struct xtrivial_default_construct_impl<false, T> : std::has_trivial_default_constructor<T> {};
}

template <class T>
using xtrivially_default_constructible = detail::xtrivial_default_construct_impl<is_complete<std::is_trivially_default_constructible<double>>::value, T>;

#pragma clang diagnostic pop
#else
// CLANG && ( APPLE || EMSCRIPTEN )
#if !defined(__GNUG__) || defined(_LIBCPP_VERSION) || defined(_GLIBCXX_USE_CXX11_ABI)

template <class T>
using xtrivially_default_constructible = std::is_trivially_default_constructible<T>;

#endif
#else
// NOT CLANG
#if defined(__GNUC__) && (__GNUC__ < 5 || (__GNUC__ == 5 && __GNUC_MINOR__ < 1))
// OLD GCC

template <class T>
using xtrivially_default_constructible = std::has_trivial_default_constructor<T>;

#else

template <class T>
using xtrivially_default_constructible = std::is_trivially_default_constructible<T>;
using xtrivially_default_constructible = std::has_trivial_default_constructor<T>;

#endif

#endif

}

#endif

0 comments on commit a8d6ffb

Please sign in to comment.