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

Side by Side Diff: base/template_util.h

Issue 2583353002: Make bit_cast fail if the source or dest are not trivially copyable (Closed)
Patch Set: bitcast: fixes Created 4 years 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 unified diff | Download patch
« no previous file with comments | « base/bit_cast_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_TEMPLATE_UTIL_H_ 5 #ifndef BASE_TEMPLATE_UTIL_H_
6 #define BASE_TEMPLATE_UTIL_H_ 6 #define BASE_TEMPLATE_UTIL_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <iosfwd> 9 #include <iosfwd>
10 #include <type_traits> 10 #include <type_traits>
11 #include <utility> 11 #include <utility>
12 12
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 14
15 // This hacks around libstdc++ 4.6 missing stuff in type_traits, while we need 15 // This hacks around libstdc++ 4.6 missing stuff in type_traits, while we need
16 // to support it. 16 // to support it.
17 #define CR_GLIBCXX_4_7_0 20120322 17 #define CR_GLIBCXX_4_7_0 20120322
18 #define CR_GLIBCXX_4_5_4 20120702 18 #define CR_GLIBCXX_4_5_4 20120702
19 #define CR_GLIBCXX_4_6_4 20121127 19 #define CR_GLIBCXX_4_6_4 20121127
20 #if defined(__GLIBCXX__) && \ 20 #if defined(__GLIBCXX__) && \
21 (__GLIBCXX__ < CR_GLIBCXX_4_7_0 || __GLIBCXX__ == CR_GLIBCXX_4_5_4 || \ 21 (__GLIBCXX__ < CR_GLIBCXX_4_7_0 || __GLIBCXX__ == CR_GLIBCXX_4_5_4 || \
22 __GLIBCXX__ == CR_GLIBCXX_4_6_4) 22 __GLIBCXX__ == CR_GLIBCXX_4_6_4)
23 #define CR_USE_FALLBACKS_FOR_OLD_GLIBCXX 23 #define CR_USE_FALLBACKS_FOR_OLD_GLIBCXX
24 #endif 24 #endif
25 25
26 // Some chromeos bots are using experimental 5.0 for some reason
27 // which has partial support for type_traits, but misses a smaller subset
28 // while removing some of the older non-standard stuff.
29 #define CR_GLIBCXX_5_0_0 20150123
30 #if defined(__GLIBCXX__) && (__GLIBCXX__ == CR_GLIBCXX_5_0_0)
31 #define CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX
32 #endif
33
34 // This hacks around using gcc with libc++ which has some incompatibilies.
35 // - is_trivially_* doesn't work: https://llvm.org/bugs/show_bug.cgi?id=27538
36 // TODO(danakj): Remove this when android builders are all using a newer version
37 // of gcc, or the android ndk is updated to a newer libc++ that works with older
38 // gcc versions.
39 #if !defined(__clang__) && defined(_LIBCPP_VERSION)
40 #define CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX
41 #endif
42
26 namespace base { 43 namespace base {
27 44
28 template <class T> struct is_non_const_reference : std::false_type {}; 45 template <class T> struct is_non_const_reference : std::false_type {};
29 template <class T> struct is_non_const_reference<T&> : std::true_type {}; 46 template <class T> struct is_non_const_reference<T&> : std::true_type {};
30 template <class T> struct is_non_const_reference<const T&> : std::false_type {}; 47 template <class T> struct is_non_const_reference<const T&> : std::false_type {};
31 48
32 // is_assignable 49 // is_assignable
33 50
34 namespace internal { 51 namespace internal {
35 52
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 // TODO(crbug.com/554293): Remove this when all platforms have this in the std 136 // TODO(crbug.com/554293): Remove this when all platforms have this in the std
120 // namespace. 137 // namespace.
121 #if defined(CR_USE_FALLBACKS_FOR_OLD_GLIBCXX) 138 #if defined(CR_USE_FALLBACKS_FOR_OLD_GLIBCXX)
122 template <class T> 139 template <class T>
123 using is_trivially_destructible = std::has_trivial_destructor<T>; 140 using is_trivially_destructible = std::has_trivial_destructor<T>;
124 #else 141 #else
125 template <class T> 142 template <class T>
126 using is_trivially_destructible = std::is_trivially_destructible<T>; 143 using is_trivially_destructible = std::is_trivially_destructible<T>;
127 #endif 144 #endif
128 145
146 // is_trivially_copyable is especially hard to get right.
147 // - Older versions of libstdc++ will fail to have it like they do for other
148 // type traits. In this case we should provide it based on compiler
149 // intrinsics. This is covered by the CR_USE_FALLBACKS_FOR_OLD_GLIBCXX define.
150 // - An experimental release of gcc includes most of type_traits but misses
151 // is_trivially_copyable, so we still have to avoid using libstdc++ in this
152 // case, which is covered by CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX.
153 // - When compiling libc++ from before r239653, with a gcc compiler, the
154 // std::is_trivially_copyable can fail. So we need to work around that by not
155 // using the one in libc++ in this case. This is covered by the
156 // CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX define, and is discussed in
157 // https://llvm.org/bugs/show_bug.cgi?id=27538#c1 where they point out that
158 // in libc++'s commit r239653 this is fixed by libc++ checking for gcc 5.1.
159 // - In both of the above cases we are using the gcc compiler. When defining
160 // this ourselves on compiler intrinsics, the __is_trivially_copyable()
161 // intrinsic is not available on gcc before version 5.1 (see the discussion in
162 // https://llvm.org/bugs/show_bug.cgi?id=27538#c1 again), so we must check for
163 // that version.
164 // - When __is_trivially_copyable() is not available because we are on gcc older
165 // than 5.1, we need to fall back to something, so we use __has_trivial_copy()
166 // instead based on what was done one-off in bit_cast() previously.
167
168 // TODO(crbug.com/554293): Remove this when all platforms have this in the std
169 // namespace and it works with gcc as needed.
170 #if defined(CR_USE_FALLBACKS_FOR_OLD_GLIBCXX) || \
171 defined(CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX) || \
172 defined(CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX)
173 template <typename T>
174 struct is_trivially_copyable {
175 // TODO(danakj): Remove this when android builders are all using a newer version
176 // of gcc, or the android ndk is updated to a newer libc++ that does this for
177 // us.
178 #if _GNUC_VER >= 501
179 static constexpr bool value = __is_trivially_copyable(T);
180 #else
181 static constexpr bool value = __has_trivial_copy(T);
182 #endif
183 };
184 #else
185 template <class T>
186 using is_trivially_copyable = std::is_trivially_copyable<T>;
187 #endif
188
129 } // namespace base 189 } // namespace base
130 190
131 #undef CR_USE_FALLBACKS_FOR_OLD_GLIBCXX 191 #undef CR_USE_FALLBACKS_FOR_OLD_GLIBCXX
192 #undef CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX
193 #undef CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX
132 194
133 #endif // BASE_TEMPLATE_UTIL_H_ 195 #endif // BASE_TEMPLATE_UTIL_H_
OLDNEW
« no previous file with comments | « base/bit_cast_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698