#include <iostream>
#include <functional>
namespace sf { using Event = int ; }
class event_callback
{
std::function< bool( const sf::Event& ) > func;
public:
template< typename FN, typename... ADDITIONAL_ARGS >
event_callback( FN f, ADDITIONAL_ARGS... additional_args )
: func { std::bind( f, std::placeholders::_1, additional_args... ) } {}
bool run(const sf::Event& evt) { return func(evt); }
};
struct A
{
bool mem_fun( const sf::Event& ) { return std::cout << "A::mem_fun\n" ; }
bool mem_fun_with_more_args( sf::Event, int, char )
{ return std::cout << "A::mem_fun_with_more_args\n" ; }
};
int free_fun( sf::Event e, A& a, double d )
{
// ...
std::cout << "free_fun => " ;
return a.mem_fun_with_more_args( e, d, 'H' ) ;
}
bool logger( sf::Event ) { std::cout << "just log the event\n" ; return true ; }
int main()
{
A a ;
event_callback cb{ std::bind( &A::mem_fun, &a, std::placeholders::_1 ) } ;
cb.run(30) ;
cb = std::bind( &A::mem_fun_with_more_args, &a, std::placeholders::_1, 78, 'D' ) ;
cb.run(30) ;
cb = std::bind( free_fun, std::placeholders::_1, std::ref(a), 23.5 ) ;
cb.run(30) ;
cb = [&a]( sf::Event x ) { std::cout << "closure => " ; return a.mem_fun(x) ; } ;
cb.run(30) ;
cb = logger ;
cb.run(30) ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCm5hbWVzcGFjZSBzZiB7IHVzaW5nIEV2ZW50ID0gaW50IDsgfQoKY2xhc3MgZXZlbnRfY2FsbGJhY2sKewogICAgc3RkOjpmdW5jdGlvbjwgYm9vbCggY29uc3Qgc2Y6OkV2ZW50JiApID4gZnVuYzsKCiAgICBwdWJsaWM6CiAgICAgICAgdGVtcGxhdGU8IHR5cGVuYW1lIEZOLCB0eXBlbmFtZS4uLiBBRERJVElPTkFMX0FSR1MgPgogICAgICAgIGV2ZW50X2NhbGxiYWNrKCBGTiBmLCBBRERJVElPTkFMX0FSR1MuLi4gYWRkaXRpb25hbF9hcmdzICkKICAgICAgICAgIDogZnVuYyB7IHN0ZDo6YmluZCggZiwgc3RkOjpwbGFjZWhvbGRlcnM6Ol8xLCBhZGRpdGlvbmFsX2FyZ3MuLi4gKSB9IHt9CgogICAgYm9vbCBydW4oY29uc3Qgc2Y6OkV2ZW50JiBldnQpIHsgcmV0dXJuIGZ1bmMoZXZ0KTsgfQp9OwoKc3RydWN0IEEKewogICAgYm9vbCBtZW1fZnVuKCBjb25zdCBzZjo6RXZlbnQmICkgeyByZXR1cm4gc3RkOjpjb3V0IDw8ICJBOjptZW1fZnVuXG4iIDsgfQogICAgYm9vbCBtZW1fZnVuX3dpdGhfbW9yZV9hcmdzKCBzZjo6RXZlbnQsIGludCwgY2hhciApCiAgICB7IHJldHVybiBzdGQ6OmNvdXQgPDwgIkE6Om1lbV9mdW5fd2l0aF9tb3JlX2FyZ3NcbiIgOyB9Cn07CgppbnQgZnJlZV9mdW4oIHNmOjpFdmVudCBlLCBBJiBhLCBkb3VibGUgZCApCnsKICAgIC8vIC4uLgogICAgc3RkOjpjb3V0IDw8ICAiZnJlZV9mdW4gPT4gIiA7CiAgICByZXR1cm4gYS5tZW1fZnVuX3dpdGhfbW9yZV9hcmdzKCBlLCBkLCAnSCcgKSA7Cn0KCmJvb2wgbG9nZ2VyKCBzZjo6RXZlbnQgKSB7IHN0ZDo6Y291dCA8PCAianVzdCBsb2cgdGhlIGV2ZW50XG4iIDsgcmV0dXJuIHRydWUgOyB9CgppbnQgbWFpbigpCnsKICAgIEEgYSA7CgogICAgZXZlbnRfY2FsbGJhY2sgY2J7IHN0ZDo6YmluZCggJkE6Om1lbV9mdW4sICZhLCBzdGQ6OnBsYWNlaG9sZGVyczo6XzEgKSB9IDsKICAgIGNiLnJ1bigzMCkgOwoKICAgIGNiID0gc3RkOjpiaW5kKCAmQTo6bWVtX2Z1bl93aXRoX21vcmVfYXJncywgJmEsIHN0ZDo6cGxhY2Vob2xkZXJzOjpfMSwgNzgsICdEJyApIDsKICAgIGNiLnJ1bigzMCkgOwoKICAgIGNiID0gc3RkOjpiaW5kKCBmcmVlX2Z1biwgc3RkOjpwbGFjZWhvbGRlcnM6Ol8xLCBzdGQ6OnJlZihhKSwgMjMuNSApIDsKICAgIGNiLnJ1bigzMCkgOwoKICAgIGNiID0gWyZhXSggc2Y6OkV2ZW50IHggKSB7IHN0ZDo6Y291dCA8PCAiY2xvc3VyZSA9PiAiIDsgcmV0dXJuIGEubWVtX2Z1bih4KSA7IH0gOwogICAgY2IucnVuKDMwKSA7CgogICAgY2IgPSBsb2dnZXIgOwogICAgY2IucnVuKDMwKSA7Cn0K