ChampSim
detect.h
Go to the documentation of this file.
1 /*
2  * Copyright 2023 The ChampSim Contributors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef UTIL_DETECT_H
18 #define UTIL_DETECT_H
19 
20 /*
21  * This is a port of <experimental/type_traits> detection idiom
22  *
23  * The port is used here so as not to depend on the presence of the experimental header
24  */
25 
26 #include <type_traits>
27 
28 namespace champsim
29 {
30 namespace detail
31 {
32 template <class Default, class AlwaysVoid, template <class...> class Op, class... Args>
33 struct detector {
34  using value_t = std::false_type;
35  using type = Default;
36 };
37 
38 template <class Default, template <class...> class Op, class... Args>
39 struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
40  using value_t = std::true_type;
41  using type = Op<Args...>;
42 };
43 
44 } // namespace detail
45 
46 struct nonesuch {
47  ~nonesuch() = delete;
48  nonesuch(nonesuch const&) = delete;
49  void operator=(nonesuch const&) = delete;
50 };
51 
52 template <template <class...> class Op, class... Args>
53 using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
54 
55 template <template <class...> class Op, class... Args>
56 using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type;
57 
58 template <class Default, template <class...> class Op, class... Args>
59 using detected_or = detail::detector<Default, void, Op, Args...>;
60 
61 template <template <class...> class Op, class... Args>
62 constexpr inline bool is_detected_v = is_detected<Op, Args...>::value;
63 
64 template <class Default, template <class...> class Op, class... Args>
65 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
66 
67 template <class Expected, template <class...> class Op, class... Args>
68 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
69 
70 template <class Expected, template <class...> class Op, class... Args>
71 constexpr inline bool is_detected_exact_v = is_detected_exact<Expected, Op, Args...>::value;
72 
73 template <class To, template <class...> class Op, class... Args>
74 using is_detected_convertible = std::is_convertible<detected_t<Op, Args...>, To>;
75 
76 template <class To, template <class...> class Op, class... Args>
77 constexpr inline bool is_detected_convertible_v = is_detected_convertible<To, Op, Args...>::value;
78 } // namespace champsim
79 #endif
Definition: champsim.h:24
typename detail::detector< nonesuch, void, Op, Args... >::type detected_t
Definition: detect.h:56
typename detail::detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: detect.h:53
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: detect.h:74
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: detect.h:65
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: detect.h:68
constexpr bool is_detected_exact_v
Definition: detect.h:71
constexpr bool is_detected_convertible_v
Definition: detect.h:77
constexpr bool is_detected_v
Definition: detect.h:62
Definition: detect.h:33
std::false_type value_t
Definition: detect.h:34
Default type
Definition: detect.h:35
Definition: detect.h:46
nonesuch(nonesuch const &)=delete
void operator=(nonesuch const &)=delete