Jlm
Loading...
Searching...
No Matches
MatchType.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2025 Helge Bahmann <hcb@chaoticmind.net>
3 * See COPYING for terms of redistribution.
4 */
5
6#ifndef JLM_RVSDG_MATCH_TYPE_HPP
7#define JLM_RVSDG_MATCH_TYPE_HPP
8
9#include <stdexcept>
10#include <string>
11#include <tuple>
12
13namespace jlm::rvsdg
14{
15
22template<typename MFP>
24
25// Partial specialization to deduce type from non-const member function pointers.
26template<typename MFP, typename Ret, typename... Args>
28{
29 // Deduce for non-const member functions.
30 using type = std::tuple_element_t<0, std::tuple<Args...>>;
31};
32
33// Partial specialization to deduce type from const member function pointers.
34template<typename MFP, typename Ret, typename... Args>
36{
37 // Deduce for const member functions.
38 using type = std::tuple_element_t<0, std::tuple<Args...>>;
39};
40
47template<typename MFP>
49
50// Partial specialization to deduce type from non-const member function pointers.
51template<typename MFP, typename Ret, typename... Args>
53{
54 // Deduce for non-const member functions.
55 using type = Ret;
56};
57
58// Partial specialization to deduce type from const member function pointers.
59template<typename MFP, typename Ret, typename... Args>
61{
62 // Deduce for const member functions.
63 using type = Ret;
64};
65
72template<typename Callable>
74{
75 // Deduce for object types.
76 using type = typename member_function_pointer_argtype<decltype(&Callable::operator())>::type;
77};
78
79// Partial specialization to deduce if callabale object is a function pointer type.
80template<typename Ret, typename... Args>
82{
83 // Specialization to deduce for function pointer types.
84 using type = std::tuple_element_t<0, std::tuple<Args...>>;
85};
86
93template<typename Callable>
95{
96 // Deduce for object types.
97 using type = typename member_function_pointer_restype<decltype(&Callable::operator())>::type;
98};
99
100// Partial specialization to deduce if callable object is a function pointer type.
101template<typename Ret, typename... Args>
103{
104 // Specialization to deduce for function pointer types.
105 using type = Ret;
106};
107
122template<typename T, typename... Fns>
123void
124MatchType(T & obj, const Fns &... fns);
125
126// Specialization to handle the termination (empty handlers) case.
127template<typename T>
128void
130{}
131
132// Specialization to handle the head case.
133template<typename T, typename Fn, typename... Fns>
134void
135MatchType(T & x, const Fn & fn, const Fns &... fns)
136{
137 using S = std::remove_reference_t<typename CallableArgumentType<Fn>::type>;
138 if (auto i = dynamic_cast<S *>(&x))
139 {
140 fn(*i);
141 }
142 else
143 {
144 MatchType(x, fns...);
145 }
146};
147
165template<typename T, typename... Fns>
166void
168
169// Specialization to handle the termination (empty handlers) case.
170template<typename T, typename Fn>
172MatchTypeWithDefault(T & /* x */, const Fn & fn)
173{
174 return fn();
175}
176
177// Specialization to handle the head case.
178template<typename T, typename Fn, typename... Fns>
180MatchTypeWithDefault(T & x, const Fn & fn, const Fns &... fns)
181{
182 using S = std::remove_reference_t<typename CallableArgumentType<Fn>::type>;
183 if (auto i = dynamic_cast<S *>(&x))
184 {
185 return fn(*i);
186 }
187 else
188 {
189 return MatchTypeWithDefault(x, fns...);
190 }
191};
192
208template<typename T, typename... Fns>
209void
210MatchTypeOrFail(T & obj, const Fns &... fns);
211
212// Specialization to handle the termination (last handler) case.
213template<typename T, typename Fn>
216{
217 using S = std::remove_reference_t<typename CallableArgumentType<Fn>::type>;
218 if (auto i = dynamic_cast<S *>(&x))
219 {
220 return fn(*i);
221 }
222 else
223 {
224 throw std::logic_error(std::string("Incomplete pattern matching on ") + typeid(T).name());
225 }
226}
227
228// Specialization to handle the head case.
229template<typename T, typename Fn, typename... Fns>
231MatchTypeOrFail(T & x, const Fn & fn, const Fns &... fns)
232{
233 using S = std::remove_reference_t<typename CallableArgumentType<Fn>::type>;
234 if (auto i = dynamic_cast<S *>(&x))
235 {
236 return fn(*i);
237 }
238 else
239 {
240 return MatchTypeOrFail(x, fns...);
241 }
242};
243
244}
245
246#endif
void MatchTypeWithDefault(T &obj, const Fns &... fns)
Pattern match over subclass type of given object with default handler.
void MatchTypeOrFail(T &obj, const Fns &... fns)
Pattern match over subclass type of given object.
void MatchType(T &obj, const Fns &... fns)
Pattern match over subclass type of given object.
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
std::tuple_element_t< 0, std::tuple< Args... > > type
Definition MatchType.hpp:84
Template helper to deduce first argument of a callable object.
Definition MatchType.hpp:74
typename member_function_pointer_argtype< decltype(&Callable::operator())>::type type
Definition MatchType.hpp:76
Template helper to deduce result of a callable object.
Definition MatchType.hpp:95
typename member_function_pointer_restype< decltype(&Callable::operator())>::type type
Definition MatchType.hpp:97
std::tuple_element_t< 0, std::tuple< Args... > > type
Definition MatchType.hpp:38
std::tuple_element_t< 0, std::tuple< Args... > > type
Definition MatchType.hpp:30
Template helper to deduce argument type of member function pointer.
Definition MatchType.hpp:23
Template helper to deduce result type of member function pointer.
Definition MatchType.hpp:48