OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
jdoerrie
2017/06/20 23:51:09
base/template_util.h (https://codesearch.chromium.
dyaroshev
2017/06/22 10:41:43
Done - merged it here. Also replaced local impleme
| |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef BASE_TYPE_TRAITS_H_ | |
6 #define BASE_TYPE_TRAITS_H_ | |
7 | |
8 #include <type_traits> | |
9 | |
10 namespace base { | |
11 | |
12 // C++14 --------------------------------------------------------------------- | |
13 // These can be replaced with the ones from the standard once we have C++14. | |
14 | |
15 // std::enable_if_t: http://en.cppreference.com/w/cpp/types/enable_if | |
16 template <bool condition, typename T = void> | |
17 using enable_if_t = typename std::enable_if<condition, T>::type; | |
18 | |
19 // std::conditional_t: http://en.cppreference.com/w/cpp/types/conditional | |
20 template <bool condition, typename T, typename U> | |
21 using conditional_t = typename std::conditional<condition, T, U>::type; | |
22 | |
23 // C++17 ---------------------------------------------------------------------- | |
24 // These can be replaced with the ones from the standard once we have C++17. | |
25 | |
26 // std::void_t: http://en.cppreference.com/w/cpp/types/void_t | |
27 // Needed for the detection idiom. | |
28 template <typename...> | |
29 using void_t = void; | |
30 | |
31 // std::nonesuch: http://en.cppreference.com/w/cpp/experimental/nonesuch | |
32 // Needed for the detection idiom. | |
33 struct nonesuch { | |
34 nonesuch() = delete; | |
35 ~nonesuch() = delete; | |
36 nonesuch(nonesuch const&) = delete; | |
37 void operator=(nonesuch const&) = delete; | |
38 }; | |
39 | |
40 // Implementation of the detection idiom from cppreference: | |
41 // http://en.cppreference.com/w/cpp/experimental/is_detected | |
42 namespace internal { | |
43 | |
44 template <typename Default, | |
45 typename AlwaysVoid, | |
46 template <typename...> class Op, | |
47 typename... Args> | |
48 struct detector { | |
49 using value_t = std::false_type; | |
50 using type = Default; | |
51 }; | |
52 | |
53 template <typename Default, template <typename...> class Op, typename... Args> | |
54 struct detector<Default, void_t<Op<Args...>>, Op, Args...> { | |
55 using value_t = std::true_type; | |
56 using type = Op<Args...>; | |
57 }; | |
58 | |
59 } // namespace internal | |
60 | |
61 // std::is_detected: http://en.cppreference.com/w/cpp/experimental/is_detected | |
62 template <template <class...> class Op, typename... Args> | |
63 using is_detected = | |
64 typename internal::detector<nonesuch, void, Op, Args...>::value_t; | |
65 | |
66 // std::is_detected_v, implemented as a constexpr function instead of a variable | |
67 // template, since we don't have those. | |
68 // http://en.cppreference.com/w/cpp/experimental/is_detected | |
69 template <template <typename...> class Op, typename... Args> | |
70 constexpr bool is_detected_c() { | |
71 return is_detected<Op, Args...>::value; | |
72 } | |
73 | |
74 } // namespace base | |
75 | |
76 #endif // BASE_TYPE_TRAITS_H_ | |
OLD | NEW |