Skip to content

Instantly share code, notes, and snippets.

@kspalaiologos
Created November 15, 2024 00:44
Show Gist options
  • Save kspalaiologos/f77c520a555d7d96f6415b65ba7707ca to your computer and use it in GitHub Desktop.
Save kspalaiologos/f77c520a555d7d96f6415b65ba7707ca to your computer and use it in GitHub Desktop.
kludge to convert a cpp-style closure into a c pointer, retains data in an external structure
namespace {
template <typename F, int I, typename L, typename R, typename ...A>
inline F convert(L&& l, R (*)(A...) noexcept(noexcept(::std::declval<F>()(::std::declval<A>()...)))) {
static thread_local L l_(::std::forward<L>(l));
static thread_local bool full;
if (full) {
l_.~L();
new (static_cast<void*>(&l_)) L(::std::forward<L>(l));
} else
full = true;
struct S {
static R f(A... args) noexcept(noexcept(::std::declval<F>()(::std::forward<A>(args)...))) {
return l_(::std::forward<A>(args)...);
}
};
return &S::f;
}
}
template <typename F, int I = 0, typename L>
F convert(L&& l) {
return convert<F, I>(::std::forward<L>(l), F());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment