Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Unified Diff: base/bit_cast.h

Issue 1837563002: bit_cast: check is_trivially_copyable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix __has_feature Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/compiler_specific.h » ('j') | base/compiler_specific.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « no previous file | base/compiler_specific.h » ('j') | base/compiler_specific.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698