1
1
#pragma once
2
2
3
3
#include < cassert>
4
+ #include < type_traits>
4
5
5
6
namespace binsparse {
6
7
@@ -99,4 +100,128 @@ struct type_info<bool> {
99
100
}
100
101
};
101
102
103
+ namespace __detail {
104
+
105
+ template <typename Fn, typename ... Args>
106
+ requires (std::is_invocable_v<Fn, Args...>)
107
+ void invoke_if_able (Fn&& fn, Args&&... args)
108
+ {
109
+ std::invoke (std::forward<Fn>(fn), std::forward<Args>(args)...);
110
+ }
111
+
112
+ template <typename Fn, typename ... Args>
113
+ void invoke_if_able (Fn&& fn, Args&&... args) {}
114
+
115
+ template <typename Fn, typename ... Args>
116
+ void invoke_visit_fn_impl_ (std::vector<std::string> type_labels, Fn&& fn, Args&&... args) {
117
+ if constexpr (sizeof ...(Args) <= 3 ) {
118
+ if (type_labels.size () == 1 ) {
119
+ auto type_label = type_labels.front ();
120
+ if (type_label == " uint8" ) {
121
+ invoke_if_able (std::forward<Fn>(fn), std::uint8_t (), std::forward<Args>(args)...);
122
+ } else if (type_label == " uint16" ) {
123
+ invoke_if_able (std::forward<Fn>(fn), std::uint16_t (), std::forward<Args>(args)...);
124
+ } else if (type_label == " uint32" ) {
125
+ invoke_if_able (std::forward<Fn>(fn), std::uint32_t (), std::forward<Args>(args)...);
126
+ } else if (type_label == " uint64" ) {
127
+ invoke_if_able (std::forward<Fn>(fn), std::uint64_t (), std::forward<Args>(args)...);
128
+ } else if (type_label == " int8" ) {
129
+ invoke_if_able (std::forward<Fn>(fn), std::int8_t (), std::forward<Args>(args)...);
130
+ } else if (type_label == " int16" ) {
131
+ invoke_if_able (std::forward<Fn>(fn), std::int16_t (), std::forward<Args>(args)...);
132
+ } else if (type_label == " int32" ) {
133
+ invoke_if_able (std::forward<Fn>(fn), std::int32_t (), std::forward<Args>(args)...);
134
+ } else if (type_label == " int64" ) {
135
+ invoke_if_able (std::forward<Fn>(fn), std::int64_t (), std::forward<Args>(args)...);
136
+ } else if (type_label == " float32" ) {
137
+ invoke_if_able (std::forward<Fn>(fn), float (), std::forward<Args>(args)...);
138
+ } else if (type_label == " float64" ) {
139
+ invoke_if_able (std::forward<Fn>(fn), double (), std::forward<Args>(args)...);
140
+ } else if (type_label == " bint8" ) {
141
+ invoke_if_able (std::forward<Fn>(fn), bool (), std::forward<Args>(args)...);
142
+ } else {
143
+ assert (false );
144
+ }
145
+ } else {
146
+ auto type_label = type_labels.back ();
147
+ type_labels.pop_back ();
148
+ if (type_label == " uint8" ) {
149
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), std::uint8_t (), std::forward<Args>(args)...);
150
+ } else if (type_label == " uint16" ) {
151
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), std::uint16_t (), std::forward<Args>(args)...);
152
+ } else if (type_label == " uint32" ) {
153
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), std::uint32_t (), std::forward<Args>(args)...);
154
+ } else if (type_label == " uint64" ) {
155
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), std::uint64_t (), std::forward<Args>(args)...);
156
+ } else if (type_label == " int8" ) {
157
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), std::int8_t (), std::forward<Args>(args)...);
158
+ } else if (type_label == " int16" ) {
159
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), std::int16_t (), std::forward<Args>(args)...);
160
+ } else if (type_label == " int32" ) {
161
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), std::int32_t (), std::forward<Args>(args)...);
162
+ } else if (type_label == " int64" ) {
163
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), std::int64_t (), std::forward<Args>(args)...);
164
+ } else if (type_label == " float32" ) {
165
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), float (), std::forward<Args>(args)...);
166
+ } else if (type_label == " float64" ) {
167
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), double (), std::forward<Args>(args)...);
168
+ } else if (type_label == " bint8" ) {
169
+ invoke_visit_fn_impl_ (type_labels, std::forward<Fn>(fn), bool (), std::forward<Args>(args)...);
170
+ } else {
171
+ assert (false );
172
+ }
173
+ }
174
+ }
175
+ }
176
+
177
+ /*
178
+ template <typename Fn, typename... Args>
179
+ void invoke_visit_fn_impl_(std::vector<std::string> type_labels, Fn&& fn, Args&&... args) {
180
+ if constexpr(sizeof...(Args) < 10) {
181
+ if (type_labels.size() == 1) {
182
+ auto type_label = type_labels.front();
183
+ if (type_label == "uint8") {
184
+ invoke_if_able(std::forward<Fn>(fn), std::uint8_t(), std::forward<Args>(args)...);
185
+ } else if (type_label == "uint16") {
186
+ invoke_if_able(std::forward<Fn>(fn), std::uint16_t(), std::forward<Args>(args)...);
187
+ } else if (type_label == "uint32") {
188
+ invoke_if_able(std::forward<Fn>(fn), std::uint32_t(), std::forward<Args>(args)...);
189
+ } else if (type_label == "uint64") {
190
+ invoke_if_able(std::forward<Fn>(fn), std::uint64_t(), std::forward<Args>(args)...);
191
+ } else if (type_label == "int8") {
192
+ invoke_if_able(std::forward<Fn>(fn), std::int8_t(), std::forward<Args>(args)...);
193
+ } else if (type_label == "int16") {
194
+ invoke_if_able(std::forward<Fn>(fn), std::int16_t(), std::forward<Args>(args)...);
195
+ } else if (type_label == "int32") {
196
+ invoke_if_able(std::forward<Fn>(fn), std::int32_t(), std::forward<Args>(args)...);
197
+ } else if (type_label == "int64") {
198
+ invoke_if_able(std::forward<Fn>(fn), std::int64_t(), std::forward<Args>(args)...);
199
+ } else if (type_label == "float32") {
200
+ invoke_if_able(std::forward<Fn>(fn), float(), std::forward<Args>(args)...);
201
+ } else if (type_label == "float64") {
202
+ invoke_if_able(std::forward<Fn>(fn), double(), std::forward<Args>(args)...);
203
+ } else if (type_label == "bint8") {
204
+ invoke_if_able(std::forward<Fn>(fn), bool(), std::forward<Args>(args)...);
205
+ } else {
206
+ assert(false);
207
+ }
208
+ } else {
209
+ auto label = type_labels.back();
210
+ type_labels.pop_back();
211
+ invoke_visit_fn_impl_({label},
212
+ [=](auto&& v) {
213
+ invoke_visit_fn_impl_(type_labels, fn, v, args...);
214
+ });
215
+ }
216
+ }
217
+ }
218
+ */
219
+
220
+ } // end __detail
221
+
222
+ template <typename Fn>
223
+ inline void visit_label (const std::vector<std::string>& type_labels, Fn&& fn) {
224
+ __detail::invoke_visit_fn_impl_ (type_labels, fn);
225
+ }
226
+
102
227
} // end binsparse
0 commit comments