Chromium Code Reviews| Index: base/bit_cast.h |
| diff --git a/base/bit_cast.h b/base/bit_cast.h |
| index b548467e7b86ba8b032c331b39abffcb74b21644..4b347ba773137cff10db144faafd69fe687f83b2 100644 |
| --- a/base/bit_cast.h |
| +++ b/base/bit_cast.h |
| @@ -6,6 +6,9 @@ |
| #define BASE_BIT_CAST_H_ |
| #include <string.h> |
| +#include <type_traits> |
| + |
| +#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 +57,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 defined(__has_feature) && __has_feature(is_trivially_copyable) |
|
Nico
2016/03/31 22:28:15
this has to be on two lines:
../../base/bit_cast.
|
| + // 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; |