#include <boost/optional.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <ostream>
using namespace std;
template<unsigned ID,typename Functor>
boost::optional<Functor> &get_local()
{
static boost::optional<Functor> local;
return local;
}
template<unsigned ID,typename Functor>
typename Functor::result_type wrapper()
{
return get_local<ID,Functor>().get()();
}
template<typename ReturnType>
struct Func
{
typedef ReturnType (*type)();
};
template<unsigned ID,typename Functor>
typename Func<typename Functor::result_type>::type get_wrapper(Functor f)
{
(get_local<ID,Functor>()) = f;
return wrapper<ID,Functor>;
}
// ----------------------------------------------------------------------
void test(void (*fptr)())
{
fptr();
}
struct SomeStruct
{
int data;
void some_method()
{
cout << data << endl;
}
void another_method()
{
cout << -data << endl;
}
};
int main()
{
SomeStruct local[] = { {11}, {22}, {33} };
test(get_wrapper<0>( boost::bind(&SomeStruct::some_method,local[0]) ));
test(get_wrapper<1>( boost::bind(&SomeStruct::another_method,local[0]) ));
test(get_wrapper<2>( boost::bind(&SomeStruct::some_method,local[1]) ));
test(get_wrapper<3>( boost::bind(&SomeStruct::another_method,local[1]) ));
test(get_wrapper<4>( boost::bind(&SomeStruct::some_method,local[2]) ));
test(get_wrapper<5>( boost::bind(&SomeStruct::another_method,local[2]) ));
}
I2luY2x1ZGUgPGJvb3N0L29wdGlvbmFsLmhwcD4KI2luY2x1ZGUgPGJvb3N0L2JpbmQuaHBwPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8dW5zaWduZWQgSUQsdHlwZW5hbWUgRnVuY3Rvcj4KYm9vc3Q6Om9wdGlvbmFsPEZ1bmN0b3I+ICZnZXRfbG9jYWwoKQp7CiAgICBzdGF0aWMgYm9vc3Q6Om9wdGlvbmFsPEZ1bmN0b3I+IGxvY2FsOwogICAgcmV0dXJuIGxvY2FsOwp9Cgp0ZW1wbGF0ZTx1bnNpZ25lZCBJRCx0eXBlbmFtZSBGdW5jdG9yPgp0eXBlbmFtZSBGdW5jdG9yOjpyZXN1bHRfdHlwZSB3cmFwcGVyKCkKewogICAgcmV0dXJuIGdldF9sb2NhbDxJRCxGdW5jdG9yPigpLmdldCgpKCk7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFJldHVyblR5cGU+CnN0cnVjdCBGdW5jCnsKICAgIHR5cGVkZWYgUmV0dXJuVHlwZSAoKnR5cGUpKCk7Cn07Cgp0ZW1wbGF0ZTx1bnNpZ25lZCBJRCx0eXBlbmFtZSBGdW5jdG9yPgp0eXBlbmFtZSBGdW5jPHR5cGVuYW1lIEZ1bmN0b3I6OnJlc3VsdF90eXBlPjo6dHlwZSBnZXRfd3JhcHBlcihGdW5jdG9yIGYpCnsKICAgIChnZXRfbG9jYWw8SUQsRnVuY3Rvcj4oKSkgPSBmOwogICAgcmV0dXJuIHdyYXBwZXI8SUQsRnVuY3Rvcj47Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgdGVzdCh2b2lkICgqZnB0cikoKSkKewogICAgZnB0cigpOwp9CgpzdHJ1Y3QgU29tZVN0cnVjdAp7CiAgICBpbnQgZGF0YTsKICAgIHZvaWQgc29tZV9tZXRob2QoKQogICAgewogICAgICAgIGNvdXQgPDwgZGF0YSA8PCBlbmRsOwogICAgfQogICAgdm9pZCBhbm90aGVyX21ldGhvZCgpCiAgICB7CiAgICAgICAgY291dCA8PCAtZGF0YSA8PCBlbmRsOwogICAgfQp9OwoKaW50IG1haW4oKQp7CiAgICBTb21lU3RydWN0IGxvY2FsW10gPSB7IHsxMX0sIHsyMn0sIHszM30gfTsKCiAgICB0ZXN0KGdldF93cmFwcGVyPDA+KCAgYm9vc3Q6OmJpbmQoJlNvbWVTdHJ1Y3Q6OnNvbWVfbWV0aG9kLGxvY2FsWzBdKSApKTsKICAgIHRlc3QoZ2V0X3dyYXBwZXI8MT4oICBib29zdDo6YmluZCgmU29tZVN0cnVjdDo6YW5vdGhlcl9tZXRob2QsbG9jYWxbMF0pICkpOwoKICAgIHRlc3QoZ2V0X3dyYXBwZXI8Mj4oICBib29zdDo6YmluZCgmU29tZVN0cnVjdDo6c29tZV9tZXRob2QsbG9jYWxbMV0pICkpOwogICAgdGVzdChnZXRfd3JhcHBlcjwzPiggIGJvb3N0OjpiaW5kKCZTb21lU3RydWN0Ojphbm90aGVyX21ldGhvZCxsb2NhbFsxXSkgKSk7CgogICAgdGVzdChnZXRfd3JhcHBlcjw0PiggIGJvb3N0OjpiaW5kKCZTb21lU3RydWN0Ojpzb21lX21ldGhvZCxsb2NhbFsyXSkgKSk7CiAgICB0ZXN0KGdldF93cmFwcGVyPDU+KCAgYm9vc3Q6OmJpbmQoJlNvbWVTdHJ1Y3Q6OmFub3RoZXJfbWV0aG9kLGxvY2FsWzJdKSApKTsKfQo=