OLD | NEW |
---|---|
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 || __GLIBCXX__ == CR_GLIBCXX_5_0_0) |
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 | |
dcheng
2016/12/21 20:50:18
Doesn't line 22 reference this? Should we delete a
danakj
2016/12/21 20:58:38
Oops, ya removing the 22 one.
| |
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 Loading... | |
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 intrinsics. | |
dcheng
2016/12/21 20:50:18
Nit: I find bulleted lists in comments to be easie
danakj
2016/12/21 20:58:38
k
| |
149 // 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 git commit eeeada1c7, with gcc compiler, | |
dcheng
2016/12/21 20:50:18
I'm guessing this is not a Chromium commit hash, s
danakj
2016/12/21 20:58:38
Youre right, I got it from the bug, but it is r239
| |
154 // the std::is_trivially_copyable can fail. So we need to work around that by | |
155 // not 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 eeeada1c7 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_ |
OLD | NEW |