| Index: base/bit_cast.h
|
| diff --git a/base/bit_cast.h b/base/bit_cast.h
|
| index b548467e7b86ba8b032c331b39abffcb74b21644..ad38238beb5c08902691dc3a9c8a67784714595c 100644
|
| --- a/base/bit_cast.h
|
| +++ b/base/bit_cast.h
|
| @@ -6,6 +6,10 @@
|
| #define BASE_BIT_CAST_H_
|
|
|
| #include <string.h>
|
| +#include <type_traits>
|
| +
|
| +#include "base/compiler_specific.h"
|
| +#include "build/build_config.h"
|
|
|
| // bit_cast<Dest,Source> is a template function that implements the equivalent
|
| // of "*reinterpret_cast<Dest*>(&source)". We need this in very low-level
|
| @@ -54,15 +58,38 @@
|
| // calls to memcpy() with inline object code when the size argument is a
|
| // compile-time constant. On a 32-bit system, memcpy(d,s,4) compiles to one
|
| // load and one store, and memcpy(d,s,8) compiles to two loads and two stores.
|
| -//
|
| -// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
|
| -// is likely to surprise you.
|
|
|
| template <class Dest, class Source>
|
| inline Dest bit_cast(const Source& source) {
|
| static_assert(sizeof(Dest) == sizeof(Source),
|
| "bit_cast requires source and destination to be the same size");
|
|
|
| +#if ((defined(__GLIBCXX__) && (__GLIBCXX__ >= 20150422)) || \
|
| + defined(_LIBCPP_VERSION))
|
| + // GCC 5.1 contains the first libstdc++ with is_trivially_copyable.
|
| + // Assume libc++ Just Works: is_trivially_copyable added on May 13th 2011.
|
| + static_assert(std::is_trivially_copyable<Dest>::value,
|
| + "non-trivially-copyable bit_cast is undefined");
|
| + static_assert(std::is_trivially_copyable<Source>::value,
|
| + "non-trivially-copyable bit_cast is undefined");
|
| +#elif __has_feature(is_trivially_copyable)
|
| + // The compiler supports an equivalent intrinsic.
|
| + static_assert(__is_trivially_copyable(Dest),
|
| + "non-trivially-copyable bit_cast is undefined");
|
| + static_assert(__is_trivially_copyable(Source),
|
| + "non-trivially-copyable bit_cast is undefined");
|
| +#elif COMPILER_GCC
|
| + // Fallback to compiler intrinsic on GCC and clang (which pretends to be
|
| + // GCC). This isn't quite the same as is_trivially_copyable but it'll do for
|
| + // our purpose.
|
| + static_assert(__has_trivial_copy(Dest),
|
| + "non-trivially-copyable bit_cast is undefined");
|
| + static_assert(__has_trivial_copy(Source),
|
| + "non-trivially-copyable bit_cast is undefined");
|
| +#else
|
| + // Do nothing, let the bots handle it.
|
| +#endif
|
| +
|
| Dest dest;
|
| memcpy(&dest, &source, sizeof(dest));
|
| return dest;
|
|
|