// Some metaprogramming boilerplate:
#include <tuple>
template<int...> struct seq {};
template<int Min, int Max, int... s> struct make_seq:make_seq<Min, Max-1, Max-1, s...> {};
template<int Min, int... s> struct make_seq<Min, Min, s...> {
typedef seq<s...> type;
};
template<int Max, int Min=0>
using MakeSeq = typename make_seq<Min, Max>::type;
// helper to unpack a tuple:
template<typename Func, Func f, typename Tuple, int... s>
void do_call( seq<s...>, Tuple&& tup ) {
f( std::get<s>(tup)... );
}
// Type of the resulting function pointer:
typedef void(*pvoidary)(void*);
template<typename FuncType, FuncType Func, typename... Args>
std::tuple<pvoidary, std::tuple<Args...>*> make_task( Args&&... args ) {
typedef std::tuple<Args...> pack;
pack* pvoid = new pack( std::forward<Args>(args)... );
return std::make_tuple(
[](void* pdata)->void {
pack* ppack = reinterpret_cast<pack*>(pdata);
do_call<FuncType, Func>( MakeSeq<sizeof...(Args)>(), *ppack );
},
pvoid
);
}
#define MAKE_TASK( FUNC ) make_task< typename std::decay<decltype(FUNC)>::type, FUNC >
#include <iostream>
void test( int x ) {
std::cout << "X:" << x << "\n";
}
void test2( std::string s ) {
std::cout << "S:" << s.c_str() << "\n";
}
int main() {
auto task = MAKE_TASK(test)( 7 );
pvoidary pFunc;
void* pVoid;
std::tie(pFunc, pVoid) = task;
pFunc(pVoid);
delete std::get<1>(task); // cleanup of the "void*"
auto task2 = MAKE_TASK(test2)("hello");
std::tie(pFunc, pVoid) = task2;
pFunc(pVoid);
delete std::get<1>(task2); // cleanup of the "void*"
}
Ly8gU29tZSBtZXRhcHJvZ3JhbW1pbmcgYm9pbGVycGxhdGU6CgojaW5jbHVkZSA8dHVwbGU+Cgp0ZW1wbGF0ZTxpbnQuLi4+IHN0cnVjdCBzZXEge307CnRlbXBsYXRlPGludCBNaW4sIGludCBNYXgsIGludC4uLiBzPiBzdHJ1Y3QgbWFrZV9zZXE6bWFrZV9zZXE8TWluLCBNYXgtMSwgTWF4LTEsIHMuLi4+IHt9Owp0ZW1wbGF0ZTxpbnQgTWluLCBpbnQuLi4gcz4gc3RydWN0IG1ha2Vfc2VxPE1pbiwgTWluLCBzLi4uPiB7CiAgdHlwZWRlZiBzZXE8cy4uLj4gdHlwZTsKfTsKdGVtcGxhdGU8aW50IE1heCwgaW50IE1pbj0wPgp1c2luZyBNYWtlU2VxID0gdHlwZW5hbWUgbWFrZV9zZXE8TWluLCBNYXg+Ojp0eXBlOwoKLy8gaGVscGVyIHRvIHVucGFjayBhIHR1cGxlOgp0ZW1wbGF0ZTx0eXBlbmFtZSBGdW5jLCBGdW5jIGYsIHR5cGVuYW1lIFR1cGxlLCBpbnQuLi4gcz4Kdm9pZCBkb19jYWxsKCBzZXE8cy4uLj4sIFR1cGxlJiYgdHVwICkgewogIGYoIHN0ZDo6Z2V0PHM+KHR1cCkuLi4gKTsKfQoKLy8gVHlwZSBvZiB0aGUgcmVzdWx0aW5nIGZ1bmN0aW9uIHBvaW50ZXI6CnR5cGVkZWYgdm9pZCgqcHZvaWRhcnkpKHZvaWQqKTsKCnRlbXBsYXRlPHR5cGVuYW1lIEZ1bmNUeXBlLCBGdW5jVHlwZSBGdW5jLCB0eXBlbmFtZS4uLiBBcmdzPgpzdGQ6OnR1cGxlPHB2b2lkYXJ5LCBzdGQ6OnR1cGxlPEFyZ3MuLi4+Kj4gbWFrZV90YXNrKCBBcmdzJiYuLi4gYXJncyApIHsKICAgIHR5cGVkZWYgc3RkOjp0dXBsZTxBcmdzLi4uPiBwYWNrOwogICAgcGFjayogcHZvaWQgPSBuZXcgcGFjayggc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uICk7CiAgICByZXR1cm4gc3RkOjptYWtlX3R1cGxlKAogICAgICAgIFtdKHZvaWQqIHBkYXRhKS0+dm9pZCB7CiAgICAgICAgICAgIHBhY2sqIHBwYWNrID0gcmVpbnRlcnByZXRfY2FzdDxwYWNrKj4ocGRhdGEpOwogICAgICAgICAgICBkb19jYWxsPEZ1bmNUeXBlLCBGdW5jPiggTWFrZVNlcTxzaXplb2YuLi4oQXJncyk+KCksICpwcGFjayApOwogICAgICAgIH0sCiAgICAgICAgcHZvaWQKICAgICk7Cn0KI2RlZmluZSBNQUtFX1RBU0soIEZVTkMgKSBtYWtlX3Rhc2s8IHR5cGVuYW1lIHN0ZDo6ZGVjYXk8ZGVjbHR5cGUoRlVOQyk+Ojp0eXBlLCBGVU5DID4KCiNpbmNsdWRlIDxpb3N0cmVhbT4KCgp2b2lkIHRlc3QoIGludCB4ICkgewogIHN0ZDo6Y291dCA8PCAiWDoiIDw8IHggPDwgIlxuIjsKfQp2b2lkIHRlc3QyKCBzdGQ6OnN0cmluZyBzICkgewogIHN0ZDo6Y291dCA8PCAiUzoiIDw8IHMuY19zdHIoKSA8PCAiXG4iOwp9CmludCBtYWluKCkgewogIGF1dG8gdGFzayA9IE1BS0VfVEFTSyh0ZXN0KSggNyApOwogIHB2b2lkYXJ5IHBGdW5jOwogIHZvaWQqIHBWb2lkOwogIHN0ZDo6dGllKHBGdW5jLCBwVm9pZCkgPSB0YXNrOwogIHBGdW5jKHBWb2lkKTsKICBkZWxldGUgc3RkOjpnZXQ8MT4odGFzayk7IC8vIGNsZWFudXAgb2YgdGhlICJ2b2lkKiIKICBhdXRvIHRhc2syID0gTUFLRV9UQVNLKHRlc3QyKSgiaGVsbG8iKTsKICBzdGQ6OnRpZShwRnVuYywgcFZvaWQpID0gdGFzazI7CiAgcEZ1bmMocFZvaWQpOwogIGRlbGV0ZSBzdGQ6OmdldDwxPih0YXNrMik7IC8vIGNsZWFudXAgb2YgdGhlICJ2b2lkKiIKfQo=