#include <utility>
#include <iostream>
#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=1>
using MakeSeq = typename make_seq<Min, Max>::type;
template<typename Func, typename Tuple, int... s>
void do_call( Func&& f, seq<s...>, Tuple&& tup ) {
std::forward<Func>(f)( std::get<s>(std::forward<Tuple>(tup))... );
}
typedef void(*pvoidary)(void*);
template<typename Lambda>
struct pvoidary_factory {
Lambda func;
pvoidary_factory( Lambda const& f ):func(f) {}
pvoidary_factory( pvoidary_factory const& ) = default;
pvoidary_factory( pvoidary_factory && ) = default;
template<typename... Args>
std::tuple<pvoidary, void*> operator()(Args&&... args) const {
typedef std::tuple<Lambda, Args...> package;
void* pVoid = new package(func, std::forward<Args>(args)...);
return std::make_tuple(
[](void* pVoid) {
package* pPack = reinterpret_cast<package*>(pVoid);
do_call( std::get<0>(*pPack), MakeSeq<sizeof...(Args)+1, 1>(), *pPack );
},
pVoid
);
}
};
template<typename Lambda>
pvoidary_factory<Lambda> Wrap( Lambda const& func ) {
return {func};
}
int main() {
int x = 7;
auto factory = Wrap( [x]( int y, double d ) {
std::cout << "X:" << x << "Y:" << y << "D:" << d << "\n";
} );
void* pvoid;
pvoidary pfunc; // void(*)(void*)
std::tie( pfunc, pvoid ) = factory( 10, 3.14 ); // bind y and d here
pfunc( pvoid ); // calls the wrapped method
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHR1cGxlPiAgICAKCgp0ZW1wbGF0ZTxpbnQuLi4+IHN0cnVjdCBzZXEge307CnRlbXBsYXRlPGludCBNaW4sIGludCBNYXgsIGludC4uLiBzPiBzdHJ1Y3QgbWFrZV9zZXE6bWFrZV9zZXE8TWluLCBNYXgtMSwgTWF4LTEsIHMuLi4+IHt9Owp0ZW1wbGF0ZTxpbnQgTWluLCBpbnQuLi4gcz4gc3RydWN0IG1ha2Vfc2VxPE1pbiwgTWluLCBzLi4uPiB7CiAgdHlwZWRlZiBzZXE8cy4uLj4gdHlwZTsKfTsKdGVtcGxhdGU8aW50IE1heCwgaW50IE1pbj0xPgp1c2luZyBNYWtlU2VxID0gdHlwZW5hbWUgbWFrZV9zZXE8TWluLCBNYXg+Ojp0eXBlOwoKdGVtcGxhdGU8dHlwZW5hbWUgRnVuYywgdHlwZW5hbWUgVHVwbGUsIGludC4uLiBzPgp2b2lkIGRvX2NhbGwoIEZ1bmMmJiBmLCBzZXE8cy4uLj4sIFR1cGxlJiYgdHVwICkgewogIHN0ZDo6Zm9yd2FyZDxGdW5jPihmKSggc3RkOjpnZXQ8cz4oc3RkOjpmb3J3YXJkPFR1cGxlPih0dXApKS4uLiApOwp9Cgp0eXBlZGVmIHZvaWQoKnB2b2lkYXJ5KSh2b2lkKik7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBMYW1iZGE+CnN0cnVjdCBwdm9pZGFyeV9mYWN0b3J5IHsKICBMYW1iZGEgZnVuYzsKICBwdm9pZGFyeV9mYWN0b3J5KCBMYW1iZGEgY29uc3QmIGYgKTpmdW5jKGYpIHt9CiAgcHZvaWRhcnlfZmFjdG9yeSggcHZvaWRhcnlfZmFjdG9yeSBjb25zdCYgKSA9IGRlZmF1bHQ7CiAgcHZvaWRhcnlfZmFjdG9yeSggcHZvaWRhcnlfZmFjdG9yeSAmJiApID0gZGVmYXVsdDsKICB0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBBcmdzPgogIHN0ZDo6dHVwbGU8cHZvaWRhcnksIHZvaWQqPiBvcGVyYXRvcigpKEFyZ3MmJi4uLiBhcmdzKSBjb25zdCB7CiAgICB0eXBlZGVmIHN0ZDo6dHVwbGU8TGFtYmRhLCBBcmdzLi4uPiBwYWNrYWdlOwogICAgdm9pZCogcFZvaWQgPSBuZXcgcGFja2FnZShmdW5jLCBzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwogICAgcmV0dXJuIHN0ZDo6bWFrZV90dXBsZSgKICAgICAgW10odm9pZCogcFZvaWQpIHsKICAgICAgICBwYWNrYWdlKiBwUGFjayA9IHJlaW50ZXJwcmV0X2Nhc3Q8cGFja2FnZSo+KHBWb2lkKTsKICAgICAgICBkb19jYWxsKCBzdGQ6OmdldDwwPigqcFBhY2spLCBNYWtlU2VxPHNpemVvZi4uLihBcmdzKSsxLCAxPigpLCAqcFBhY2sgKTsKICAgICAgfSwKICAgICAgcFZvaWQKICAgICk7CiAgfQp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBMYW1iZGE+CnB2b2lkYXJ5X2ZhY3Rvcnk8TGFtYmRhPiBXcmFwKCBMYW1iZGEgY29uc3QmIGZ1bmMgKSB7CiAgcmV0dXJuIHtmdW5jfTsKfQoKaW50IG1haW4oKSB7CiAgaW50IHggPSA3OwogIGF1dG8gZmFjdG9yeSA9IFdyYXAoIFt4XSggaW50IHksIGRvdWJsZSBkICkgewogICAgc3RkOjpjb3V0IDw8ICJYOiIgPDwgeCA8PCAiWToiIDw8IHkgPDwgIkQ6IiA8PCBkIDw8ICJcbiI7CiAgfSApOwogIHZvaWQqIHB2b2lkOwogIHB2b2lkYXJ5IHBmdW5jOyAvLyB2b2lkKCopKHZvaWQqKQogIHN0ZDo6dGllKCBwZnVuYywgcHZvaWQgKSA9IGZhY3RvcnkoIDEwLCAzLjE0ICk7IC8vIGJpbmQgeSBhbmQgZCBoZXJlCiAgcGZ1bmMoIHB2b2lkICk7IC8vIGNhbGxzIHRoZSB3cmFwcGVkIG1ldGhvZAp9