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 <iterator> |
10 #include <type_traits> | 11 #include <type_traits> |
11 #include <utility> | 12 #include <utility> |
12 | 13 |
13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
14 | 15 |
15 // Some versions of libstdc++ have partial support for type_traits, but misses | 16 // Some versions of libstdc++ have partial support for type_traits, but misses |
16 // a smaller subset while removing some of the older non-standard stuff. Assume | 17 // a smaller subset while removing some of the older non-standard stuff. Assume |
17 // that all versions below 5.0 fall in this category, along with one 5.0 | 18 // that all versions below 5.0 fall in this category, along with one 5.0 |
18 // experimental release. Test for this by consulting compiler major version, | 19 // experimental release. Test for this by consulting compiler major version, |
19 // the only reliable option available, so theoretically this could fail should | 20 // the only reliable option available, so theoretically this could fail should |
(...skipping 13 matching lines...) Expand all Loading... |
33 #if !defined(__clang__) && defined(_LIBCPP_VERSION) | 34 #if !defined(__clang__) && defined(_LIBCPP_VERSION) |
34 #define CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX | 35 #define CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX |
35 #endif | 36 #endif |
36 | 37 |
37 namespace base { | 38 namespace base { |
38 | 39 |
39 template <class T> struct is_non_const_reference : std::false_type {}; | 40 template <class T> struct is_non_const_reference : std::false_type {}; |
40 template <class T> struct is_non_const_reference<T&> : std::true_type {}; | 41 template <class T> struct is_non_const_reference<T&> : std::true_type {}; |
41 template <class T> struct is_non_const_reference<const T&> : std::false_type {}; | 42 template <class T> struct is_non_const_reference<const T&> : std::false_type {}; |
42 | 43 |
| 44 template <typename...> |
| 45 struct make_void { |
| 46 using type = void; |
| 47 }; |
| 48 |
| 49 // A clone of C++17 std::void_t. |
| 50 // Unlike the original version, we need |make_void| as a helper struct to avoid |
| 51 // a C++14 defect. |
| 52 // ref: http://en.cppreference.com/w/cpp/types/void_t |
| 53 // ref: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558 |
| 54 template <typename... Ts> |
| 55 using void_t = typename make_void<Ts...>::type; |
| 56 |
43 namespace internal { | 57 namespace internal { |
44 | 58 |
45 template <typename...> | 59 template <typename...> |
46 struct make_void { | 60 struct make_void { |
47 using type = void; | 61 using type = void; |
48 }; | 62 }; |
49 | 63 |
50 // A clone of C++17 std::void_t. | 64 // A clone of C++17 std::void_t. |
51 // Unlike the original version, we need |make_void| as a helper struct to avoid | 65 // Unlike the original version, we need |make_void| as a helper struct to avoid |
52 // a C++14 defect. | 66 // a C++14 defect. |
53 // ref: http://en.cppreference.com/w/cpp/types/void_t | 67 // ref: http://en.cppreference.com/w/cpp/types/void_t |
54 // ref: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558 | 68 // ref: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558 |
55 template <typename... Ts> | 69 template <typename... Ts> |
56 using void_t = typename make_void<Ts...>::type; | 70 using void_t = typename make_void<Ts...>::type; |
57 | 71 |
58 // Uses expression SFINAE to detect whether using operator<< would work. | 72 // Uses expression SFINAE to detect whether using operator<< would work. |
59 template <typename T, typename = void> | 73 template <typename T, typename = void> |
60 struct SupportsOstreamOperator : std::false_type {}; | 74 struct SupportsOstreamOperator : std::false_type {}; |
61 template <typename T> | 75 template <typename T> |
62 struct SupportsOstreamOperator<T, | 76 struct SupportsOstreamOperator<T, |
63 decltype(void(std::declval<std::ostream&>() | 77 decltype(void(std::declval<std::ostream&>() |
64 << std::declval<T>()))> | 78 << std::declval<T>()))> |
65 : std::true_type {}; | 79 : std::true_type {}; |
66 | 80 |
| 81 // Used to detech whether the given type is an iterator. This is normally used |
| 82 // with std::enable_if to provide disambiguation for functions that take |
| 83 // templatzed iterators as input. |
| 84 template <typename T, typename = void> |
| 85 struct is_iterator : std::false_type {}; |
| 86 |
| 87 template <typename T> |
| 88 struct is_iterator<T, |
| 89 void_t<typename std::iterator_traits<T>::iterator_category>> |
| 90 : std::true_type {}; |
| 91 |
67 } // namespace internal | 92 } // namespace internal |
68 | 93 |
69 // is_trivially_copyable is especially hard to get right. | 94 // is_trivially_copyable is especially hard to get right. |
70 // - Older versions of libstdc++ will fail to have it like they do for other | 95 // - Older versions of libstdc++ will fail to have it like they do for other |
71 // type traits. This has become a subset of the second point, but used to be | 96 // type traits. This has become a subset of the second point, but used to be |
72 // handled independently. | 97 // handled independently. |
73 // - An experimental release of gcc includes most of type_traits but misses | 98 // - An experimental release of gcc includes most of type_traits but misses |
74 // is_trivially_copyable, so we still have to avoid using libstdc++ in this | 99 // is_trivially_copyable, so we still have to avoid using libstdc++ in this |
75 // case, which is covered by CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX. | 100 // case, which is covered by CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX. |
76 // - When compiling libc++ from before r239653, with a gcc compiler, the | 101 // - When compiling libc++ from before r239653, with a gcc compiler, the |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 // http://en.cppreference.com/w/cpp/utility/functional/less_void | 146 // http://en.cppreference.com/w/cpp/utility/functional/less_void |
122 using is_transparent = int; | 147 using is_transparent = int; |
123 }; | 148 }; |
124 | 149 |
125 } // namespace base | 150 } // namespace base |
126 | 151 |
127 #undef CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX | 152 #undef CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX |
128 #undef CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX | 153 #undef CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX |
129 | 154 |
130 #endif // BASE_TEMPLATE_UTIL_H_ | 155 #endif // BASE_TEMPLATE_UTIL_H_ |
OLD | NEW |