Chromium Code Reviews| 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 |