18template<
bool destroy_on_invoke,
typename RetType,
typename... Args>
19struct destroyable_function {
25 void operator()(
void *userdata)
const {
31 destroyable_function(Fn&& fn) : function(std::move(fn)) {}
33 RetType operator()(Args... args) {
34 std::unique_ptr<destroyable_function> destroyer;
35 if (destroy_on_invoke) {
36 destroyer = std::unique_ptr<destroyable_function>(
this);
38 return function(std::forward<Args>(args)...);
41 std::tuple<
void*, RetType (*)(
void*, Args...)> prefix_invoker() {
42 return std::make_tuple(
static_cast<void*
>(
this), invoke_prefix);
45 return std::make_tuple(
static_cast<void*
>(
this), invoke_prefix, destroy);
48 return std::make_tuple(std::unique_ptr<void, deleter>(
static_cast<void*
>(
this)), invoke_prefix);
51 return std::make_tuple(std::shared_ptr<void>(
static_cast<void*
>(
this), destroy), invoke_prefix);
54 std::tuple<RetType (*)(Args...,
void*),
void*> suffix_invoker() {
55 return std::make_tuple(invoke_suffix,
static_cast<void*
>(
this));
58 return std::make_tuple(invoke_suffix,
static_cast<void*
>(
this), destroy);
61 return std::make_tuple(invoke_suffix, std::unique_ptr<void, deleter>(
static_cast<void*
>(
this)));
64 return std::make_tuple(invoke_suffix, std::shared_ptr<void>(
static_cast<void*
>(
this), destroy));
67 static RetType invoke_prefix(
void *userdata, Args... args) {
68 auto self =
static_cast<destroyable_function*
>(userdata);
69 return (*self)(std::forward<Args>(args)...);
72 static RetType invoke_suffix(Args... args,
void *userdata) {
73 auto self =
static_cast<destroyable_function*
>(userdata);
74 return (*self)(std::forward<Args>(args)...);
77 static void destroy(
void *userdata) {
78 auto self =
static_cast<destroyable_function*
>(userdata);
83 std::function<RetType(Args...)> function;
153std::tuple<std::unique_ptr<void,
typename detail::destroyable_function<
false, RetType, Args...>::deleter>, RetType (*)(
void*, Args...)>
prefix_invoker_unique(Fn&& fn) {
154 return (
new detail::destroyable_function<false, RetType, Args...>(std::move(fn)))->prefix_invoker_unique();
226std::tuple<std::unique_ptr<void,
typename detail::destroyable_function<
false, RetType, Args...>::deleter>, RetType (*)(Args...,
void*)>
suffix_invoker_unique(Fn&& fn) {
227 return (
new detail::destroyable_function<false, RetType, Args...>(std::move(fn)))->suffix_invoker_unique();