isPodLike: more precise

I tried to use isPodLike in:
  http://reviews.llvm.org/D18483

That failed because !is_class is too strict on platforms which don't yet
have is_trivially_copyable. This update tries to make isPodLike smarter
for platforms which don't have is_trivially_copyable, and AFAICT it
Should Just Work on all of them. I'll revert if the bots disagree with
me.

I'll also rename isPodLike to isTriviallyCopyable if this all works out,
since that's what the standard calls it now and one day we'll be rid of
isPodLike.

llvm-svn: 264541
This commit is contained in:
JF Bastien 2016-03-27 20:32:21 +00:00
parent b22a1d186f
commit 507d696cac
1 changed files with 13 additions and 9 deletions

View File

@ -24,12 +24,11 @@
namespace llvm { namespace llvm {
/// isPodLike - This is a type trait that is used to determine whether a given /// Type trait used to determine whether a given type can be copied around with
/// type can be copied around with memcpy instead of running ctors etc. /// memcpy instead of running ctors.
template <typename T> template <typename T> struct isPodLike {
struct isPodLike { // std::is_trivially_copyable is available in libc++ with clang, libstdc++
// std::is_trivially_copyable is available in libc++ with clang, libstdc++ // that comes with GCC 5.
// that comes with GCC 5.
#if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \ #if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \
(defined(__GNUC__) && __GNUC__ >= 5) (defined(__GNUC__) && __GNUC__ >= 5)
// If the compiler supports the is_trivially_copyable trait use it, as it // If the compiler supports the is_trivially_copyable trait use it, as it
@ -40,10 +39,15 @@ struct isPodLike {
// don't know if the standard library does. This is the case for clang in // don't know if the standard library does. This is the case for clang in
// conjunction with libstdc++ from GCC 4.x. // conjunction with libstdc++ from GCC 4.x.
static const bool value = __is_trivially_copyable(T); static const bool value = __is_trivially_copyable(T);
#elif defined(__GNUC__)
// Fallback to ye olden compiler intrinsic, which isn't as accurate as the new
// one but more widely supported.
static const bool value = __has_trivial_copy(T);
#else #else
// If we don't know anything else, we can (at least) assume that all non-class // If we really don't know anything else is_pod will do, is widely supported,
// types are PODs. // but is too strict (e.g. a user-defined ctor doesn't prevent trivial copy
static const bool value = !std::is_class<T>::value; // but prevents POD-ness).
static const bool value = std::is_pod<T>::value;
#endif #endif
}; };