11#pragma once
22
33#include < cassert>
4+ #include < type_traits>
45
56namespace binsparse {
67
@@ -99,4 +100,128 @@ struct type_info<bool> {
99100 }
100101};
101102
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+
102227} // end binsparse
0 commit comments