Chromium Code Reviews| Index: base/template_util.h |
| diff --git a/base/template_util.h b/base/template_util.h |
| index 536cad8f3a3b6f0d77dc7d28076753470d2e90bc..282db6d50caf53416dd92e534acee3a1cb5cb5e6 100644 |
| --- a/base/template_util.h |
| +++ b/base/template_util.h |
| @@ -36,20 +36,82 @@ |
| namespace base { |
| +// 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
|
| +// These can be replaced with the ones from the standard once we have C++14. |
| + |
| +// std::enable_if_t: http://en.cppreference.com/w/cpp/types/enable_if |
| +template <bool condition, typename T = void> |
| +using enable_if_t = typename std::enable_if<condition, T>::type; |
| + |
| +// std::conditional_t: http://en.cppreference.com/w/cpp/types/conditional |
| +template <bool condition, typename T, typename U> |
| +using conditional_t = typename std::conditional<condition, T, U>::type; |
| + |
| +// C++17 ---------------------------------------------------------------------- |
| +// 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.
|
| + |
| +// std::void_t: http://en.cppreference.com/w/cpp/types/void_t |
| +// Needed for the detection idiom. |
| +template <typename...> |
| +using void_t = void; |
| + |
| +// std::nonesuch: http://en.cppreference.com/w/cpp/experimental/nonesuch |
| +// Needed for the detection idiom. |
| +struct nonesuch { |
| + nonesuch() = delete; |
| + ~nonesuch() = delete; |
| + nonesuch(nonesuch const&) = delete; |
| + void operator=(nonesuch const&) = delete; |
| +}; |
| + |
| +// Implementation of the detection idiom from cppreference: |
| +// http://en.cppreference.com/w/cpp/experimental/is_detected |
| +namespace internal { |
| + |
| +template <typename Default, |
| + typename AlwaysVoid, |
| + template <typename...> class Op, |
| + typename... Args> |
| +struct detector { |
| + using value_t = std::false_type; |
| + using type = Default; |
| +}; |
| + |
| +template <typename Default, template <typename...> class Op, typename... Args> |
| +struct detector<Default, void_t<Op<Args...>>, Op, Args...> { |
| + using value_t = std::true_type; |
| + using type = Op<Args...>; |
| +}; |
| + |
| +} // namespace internal |
| + |
| +// std::is_detected: http://en.cppreference.com/w/cpp/experimental/is_detected |
| +template <template <typename...> class Op, typename... Args> |
| +using is_detected = |
| + 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.
|
| + |
| +// std::is_detected_v, implemented as a constexpr function instead of a variable |
| +// template, since we don't have those. |
| +// http://en.cppreference.com/w/cpp/experimental/is_detected |
| +template <template <typename...> class Op, typename... Args> |
| +constexpr bool is_detected_c() { |
| + 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.
|
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| + |
| template <class T> struct is_non_const_reference : std::false_type {}; |
| template <class T> struct is_non_const_reference<T&> : std::true_type {}; |
| template <class T> struct is_non_const_reference<const T&> : std::false_type {}; |
| namespace internal { |
| -// Uses expression SFINAE to detect whether using operator<< would work. |
| -template <typename T, typename = void> |
| -struct SupportsOstreamOperator : std::false_type {}; |
| template <typename T> |
| -struct SupportsOstreamOperator<T, |
| - decltype(void(std::declval<std::ostream&>() |
| - << std::declval<T>()))> |
| - : std::true_type {}; |
| +using HasOstreamOperator = |
| + decltype(std::declval<std::ostream&>() << std::declval<T>()); |
| + |
| +template <typename T> |
| +using SupportsOstreamOperator = base::is_detected<HasOstreamOperator, T>; |
| } // namespace internal |