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) |
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 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 |
| 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_ |
OLD | NEW |