Last active
July 30, 2022 16:03
-
-
Save lsem/a05653b1facc20461fdc3d433594eec3 to your computer and use it in GitHub Desktop.
f2ptr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cassert> | |
#include <cstdio> | |
#include <string> | |
using namespace std; | |
namespace f2ptr { | |
namespace details { | |
template <class...> struct type_list {}; | |
// Helper meta-function needed to derive correct signature of our C-style | |
// function. | |
template <class F> | |
struct func_traits : public func_traits<decltype(&F::operator())> {}; | |
template <class ClassType, class R, class... Args> | |
struct func_traits<R (ClassType::*)(Args...) const> { | |
using return_type = R; | |
using args_type = type_list<Args...>; | |
}; | |
class f2ptr_impl { | |
public: | |
template <class F> static auto get(F f) { | |
return get_impl(typename func_traits<F>::args_type{}, std::move(f)); | |
} | |
private: | |
template <class F, class... Args> | |
static auto get_impl(type_list<Args...>, F f) { | |
static F std_func = std::move(f); | |
return +[](Args... args) -> | |
typename func_traits<F>::return_type { return std_func(args...); }; | |
} | |
}; | |
} // namespace details | |
template <class F> auto f2ptr(F f) { | |
return details::f2ptr_impl::get(std::move(f)); | |
} | |
} // namespace f2ptr | |
void take_callbacks(void (*cb1)(int, char), void (*cb2)(int)); | |
int main() { | |
int local_i = 0; | |
take_callbacks(f2ptr::f2ptr([&](int i, char) { puts("f1"); }), | |
f2ptr::f2ptr([&](int i) { puts("f2"); })); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment