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> |
(...skipping 18 matching lines...) Expand all Loading... | |
29 // - is_trivially_* doesn't work: https://llvm.org/bugs/show_bug.cgi?id=27538 | 29 // - is_trivially_* doesn't work: https://llvm.org/bugs/show_bug.cgi?id=27538 |
30 // TODO(danakj): Remove this when android builders are all using a newer version | 30 // TODO(danakj): Remove this when android builders are all using a newer version |
31 // of gcc, or the android ndk is updated to a newer libc++ that works with older | 31 // of gcc, or the android ndk is updated to a newer libc++ that works with older |
32 // gcc versions. | 32 // gcc versions. |
33 #if !defined(__clang__) && defined(_LIBCPP_VERSION) | 33 #if !defined(__clang__) && defined(_LIBCPP_VERSION) |
34 #define CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX | 34 #define CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX |
35 #endif | 35 #endif |
36 | 36 |
37 namespace base { | 37 namespace base { |
38 | 38 |
39 // C++14 --------------------------------------------------------------------- | |
danakj
2017/06/23 21:10:26
I would honestly prefer to not add things here whe
brettw
2017/06/23 21:19:45
I think all this is needed is for TransparentCompa
vmpstr
2017/06/23 21:45:14
I agree. I'd rather not start adding things from C
dyaroshev
2017/06/26 11:47:29
This is why we can't have nice things)
Ok, I foun
vmpstr
2017/06/26 15:35:53
Indeed
| |
40 // These can be replaced with the ones from the standard once we have C++14. | |
41 | |
42 // std::enable_if_t: http://en.cppreference.com/w/cpp/types/enable_if | |
43 template <bool condition, typename T = void> | |
44 using enable_if_t = typename std::enable_if<condition, T>::type; | |
45 | |
46 // std::conditional_t: http://en.cppreference.com/w/cpp/types/conditional | |
47 template <bool condition, typename T, typename U> | |
48 using conditional_t = typename std::conditional<condition, T, U>::type; | |
49 | |
50 // C++17 ---------------------------------------------------------------------- | |
51 // These can be replaced with the ones from the standard once we have C++17. | |
vmpstr
2017/06/23 21:45:14
I'll admit I'm not too familiar with the detection
dyaroshev
2017/06/26 11:47:29
Done.
| |
52 | |
53 // std::void_t: http://en.cppreference.com/w/cpp/types/void_t | |
54 // Needed for the detection idiom. | |
55 template <typename...> | |
56 using void_t = void; | |
57 | |
58 // std::nonesuch: http://en.cppreference.com/w/cpp/experimental/nonesuch | |
59 // Needed for the detection idiom. | |
60 struct nonesuch { | |
61 nonesuch() = delete; | |
62 ~nonesuch() = delete; | |
63 nonesuch(nonesuch const&) = delete; | |
64 void operator=(nonesuch const&) = delete; | |
65 }; | |
66 | |
67 // Implementation of the detection idiom from cppreference: | |
68 // http://en.cppreference.com/w/cpp/experimental/is_detected | |
69 namespace internal { | |
70 | |
71 template <typename Default, | |
72 typename AlwaysVoid, | |
73 template <typename...> class Op, | |
74 typename... Args> | |
75 struct detector { | |
76 using value_t = std::false_type; | |
77 using type = Default; | |
78 }; | |
79 | |
80 template <typename Default, template <typename...> class Op, typename... Args> | |
81 struct detector<Default, void_t<Op<Args...>>, Op, Args...> { | |
82 using value_t = std::true_type; | |
83 using type = Op<Args...>; | |
84 }; | |
85 | |
86 } // namespace internal | |
87 | |
88 // std::is_detected: http://en.cppreference.com/w/cpp/experimental/is_detected | |
89 template <template <typename...> class Op, typename... Args> | |
90 using is_detected = | |
91 typename internal::detector<nonesuch, void, Op, Args...>::value_t; | |
vmpstr
2017/06/23 21:45:14
AFAICT, we're not using detector::type, just the v
dyaroshev
2017/06/26 11:47:29
Removed altogether.
| |
92 | |
93 // std::is_detected_v, implemented as a constexpr function instead of a variable | |
94 // template, since we don't have those. | |
95 // http://en.cppreference.com/w/cpp/experimental/is_detected | |
96 template <template <typename...> class Op, typename... Args> | |
97 constexpr bool is_detected_c() { | |
98 return is_detected<Op, Args...>::value; | |
vmpstr
2017/06/23 21:45:14
Can you comment that ::value is on std::true_type/
dyaroshev
2017/06/26 11:47:29
Not applicable.
| |
99 } | |
100 | |
101 // ---------------------------------------------------------------------------- | |
102 | |
39 template <class T> struct is_non_const_reference : std::false_type {}; | 103 template <class T> struct is_non_const_reference : std::false_type {}; |
40 template <class T> struct is_non_const_reference<T&> : std::true_type {}; | 104 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 {}; | 105 template <class T> struct is_non_const_reference<const T&> : std::false_type {}; |
42 | 106 |
43 namespace internal { | 107 namespace internal { |
44 | 108 |
45 // Uses expression SFINAE to detect whether using operator<< would work. | |
46 template <typename T, typename = void> | |
47 struct SupportsOstreamOperator : std::false_type {}; | |
48 template <typename T> | 109 template <typename T> |
49 struct SupportsOstreamOperator<T, | 110 using HasOstreamOperator = |
50 decltype(void(std::declval<std::ostream&>() | 111 decltype(std::declval<std::ostream&>() << std::declval<T>()); |
51 << std::declval<T>()))> | 112 |
52 : std::true_type {}; | 113 template <typename T> |
114 using SupportsOstreamOperator = base::is_detected<HasOstreamOperator, T>; | |
53 | 115 |
54 } // namespace internal | 116 } // namespace internal |
55 | 117 |
56 // is_trivially_copyable is especially hard to get right. | 118 // is_trivially_copyable is especially hard to get right. |
57 // - Older versions of libstdc++ will fail to have it like they do for other | 119 // - Older versions of libstdc++ will fail to have it like they do for other |
58 // type traits. This has become a subset of the second point, but used to be | 120 // type traits. This has become a subset of the second point, but used to be |
59 // handled independently. | 121 // handled independently. |
60 // - An experimental release of gcc includes most of type_traits but misses | 122 // - An experimental release of gcc includes most of type_traits but misses |
61 // is_trivially_copyable, so we still have to avoid using libstdc++ in this | 123 // is_trivially_copyable, so we still have to avoid using libstdc++ in this |
62 // case, which is covered by CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX. | 124 // case, which is covered by CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 template <class T> | 156 template <class T> |
95 using is_trivially_copyable = std::is_trivially_copyable<T>; | 157 using is_trivially_copyable = std::is_trivially_copyable<T>; |
96 #endif | 158 #endif |
97 | 159 |
98 } // namespace base | 160 } // namespace base |
99 | 161 |
100 #undef CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX | 162 #undef CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX |
101 #undef CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX | 163 #undef CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX |
102 | 164 |
103 #endif // BASE_TEMPLATE_UTIL_H_ | 165 #endif // BASE_TEMPLATE_UTIL_H_ |
OLD | NEW |