template<typename A1>
struct AbstractBinder
{
virtual void call(A1 a1)=0;
virtual AbstractBinder<A1> *clone()=0;
virtual ~AbstractBinder(){}
};
template<typename A1, typename I, typename M>
struct Binder : AbstractBinder<A1>
{
Binder(I i, M m) : i_(i), m_(m) { }
void call(A1 a1)
{
(i_->*m_)(a1);
}
virtual AbstractBinder<A1> *clone()
{
return new Binder(*this);
}
I i_;
M m_;
};
template<typename A1>
class BinderHolder
{
AbstractBinder<A1> *ptr;
BinderHolder &operator=(const BinderHolder&);
public:
template<typename I, typename M>
BinderHolder(I i, M m)
: ptr(new Binder<A1,I,M>(i,m))
{
}
BinderHolder(const BinderHolder &rhs)
: ptr(rhs.ptr->clone())
{
}
~BinderHolder()
{
delete ptr;
}
void operator()(A1 a1)
{
ptr->call(a1);
}
};
template<typename A1, typename I, typename M>
BinderHolder<A1> my_bind(I i, M m) {
return BinderHolder<A1>(i, m);
}
#include <iostream>
struct Foo {
void x(int i) { std::cout << "Foo " << i << std::endl; }
};
struct Bar {
void y(int i) { std::cout << "Bar " << i << std::endl; }
};
int main()
{
Foo foo;
Bar bar;
BinderHolder<int> b1 = my_bind<int>(&foo, &Foo::x);
BinderHolder<int> b2 = my_bind<int>(&bar, &Bar::y);
b1(1);
b2(2);
}
dGVtcGxhdGU8dHlwZW5hbWUgQTE+CnN0cnVjdCBBYnN0cmFjdEJpbmRlcgp7CiAgICB2aXJ0dWFsIHZvaWQgY2FsbChBMSBhMSk9MDsKICAgIHZpcnR1YWwgQWJzdHJhY3RCaW5kZXI8QTE+ICpjbG9uZSgpPTA7CiAgICB2aXJ0dWFsIH5BYnN0cmFjdEJpbmRlcigpe30KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEExLCB0eXBlbmFtZSBJLCB0eXBlbmFtZSBNPgpzdHJ1Y3QgQmluZGVyIDogQWJzdHJhY3RCaW5kZXI8QTE+CnsKICAgIEJpbmRlcihJIGksIE0gbSkgOiBpXyhpKSwgbV8obSkgeyB9CiAgICB2b2lkIGNhbGwoQTEgYTEpCiAgICB7CiAgICAgICAgKGlfLT4qbV8pKGExKTsKICAgIH0KICAgIHZpcnR1YWwgQWJzdHJhY3RCaW5kZXI8QTE+ICpjbG9uZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBCaW5kZXIoKnRoaXMpOwogICAgfQogICAgSSBpXzsKICAgIE0gbV87Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBBMT4KY2xhc3MgQmluZGVySG9sZGVyCnsKICAgIEFic3RyYWN0QmluZGVyPEExPiAqcHRyOwogICAgQmluZGVySG9sZGVyICZvcGVyYXRvcj0oY29uc3QgQmluZGVySG9sZGVyJik7CnB1YmxpYzoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEksIHR5cGVuYW1lIE0+CiAgICBCaW5kZXJIb2xkZXIoSSBpLCBNIG0pCiAgICAgICAgOiBwdHIobmV3IEJpbmRlcjxBMSxJLE0+KGksbSkpCiAgICB7CiAgICB9CiAgICBCaW5kZXJIb2xkZXIoY29uc3QgQmluZGVySG9sZGVyICZyaHMpCiAgICAgICAgOiBwdHIocmhzLnB0ci0+Y2xvbmUoKSkKICAgIHsKICAgIH0KICAgIH5CaW5kZXJIb2xkZXIoKQogICAgewogICAgICAgIGRlbGV0ZSBwdHI7CiAgICB9CiAgICB2b2lkIG9wZXJhdG9yKCkoQTEgYTEpCiAgICB7CiAgICAgICAgcHRyLT5jYWxsKGExKTsKICAgIH0KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEExLCB0eXBlbmFtZSBJLCB0eXBlbmFtZSBNPgpCaW5kZXJIb2xkZXI8QTE+IG15X2JpbmQoSSBpLCBNIG0pIHsKICAgIHJldHVybiBCaW5kZXJIb2xkZXI8QTE+KGksIG0pOwp9CgojaW5jbHVkZSA8aW9zdHJlYW0+CgpzdHJ1Y3QgRm9vIHsKICAgIHZvaWQgeChpbnQgaSkgeyBzdGQ6OmNvdXQgPDwgIkZvbyAiIDw8IGkgPDwgc3RkOjplbmRsOyB9Cn07CgpzdHJ1Y3QgQmFyIHsKICAgIHZvaWQgeShpbnQgaSkgeyBzdGQ6OmNvdXQgPDwgIkJhciAiIDw8IGkgPDwgc3RkOjplbmRsOyB9Cn07CgppbnQgbWFpbigpCnsKICAgIEZvbyBmb287CiAgICBCYXIgYmFyOwoKICAgIEJpbmRlckhvbGRlcjxpbnQ+IGIxID0gbXlfYmluZDxpbnQ+KCZmb28sICZGb286OngpOwogICAgQmluZGVySG9sZGVyPGludD4gYjIgPSBteV9iaW5kPGludD4oJmJhciwgJkJhcjo6eSk7CgogICAgYjEoMSk7CiAgICBiMigyKTsKfQo=