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; |