#include <functional>
#include <list>
#include <iostream>
#include <string>
template <class H> struct IX {
virtual ~IX() {}
virtual void AddHandler(H handler) = 0; };
template <class A> struct Event : IX<std::function<void(A)>> {
void AddHandler(std::function<void(A)> handler) { mHandlers.push_back(std::move(handler)); }
void Fire(A argument) {
for(auto i = mHandlers.begin(), e = mHandlers.end(); i != e; ++i) {
std::function<void(A)> & handler(*i);
if(handler) {
handler(argument);
}
}
}
private:
std::list<std::function<void(A)>> mHandlers; };
struct SomeSender {
SomeSender(std::string const & name) : mName(name) { }
IX<std::function<void(std::string const &)>> & OnNameChanged(void) { return mOnNameChanged; }
void ChangeName(std::string const & name) { mName = name; mOnNameChanged.Fire(mName); }
private:
Event<std::string const &> mOnNameChanged;
std::string mName;
};
int main(void) {
SomeSender ss("Bob");
ss.OnNameChanged().AddHandler([](std::string const & name) {
std::cout << name << "!" << std::endl;
});
ss.OnNameChanged().AddHandler([](std::string const & name) {
std::cout << name << "?" << std::endl;
});
ss.ChangeName("Alice");
// ss.OnNameChanged().Fire("hoge");
std::getchar();
return 0;
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxsaXN0PgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CgoKdGVtcGxhdGUgPGNsYXNzIEg+IHN0cnVjdCBJWCB7CnZpcnR1YWwgfklYKCkge30KdmlydHVhbCB2b2lkIEFkZEhhbmRsZXIoSCBoYW5kbGVyKSA9IDA7IH07Cgp0ZW1wbGF0ZSA8Y2xhc3MgQT4gc3RydWN0IEV2ZW50IDogSVg8c3RkOjpmdW5jdGlvbjx2b2lkKEEpPj4gewp2b2lkIEFkZEhhbmRsZXIoc3RkOjpmdW5jdGlvbjx2b2lkKEEpPiBoYW5kbGVyKSB7IG1IYW5kbGVycy5wdXNoX2JhY2soc3RkOjptb3ZlKGhhbmRsZXIpKTsgfQp2b2lkIEZpcmUoQSBhcmd1bWVudCkgewoJZm9yKGF1dG8gaSA9IG1IYW5kbGVycy5iZWdpbigpLCBlID0gbUhhbmRsZXJzLmVuZCgpOyBpICE9IGU7ICsraSkgewoJCXN0ZDo6ZnVuY3Rpb248dm9pZChBKT4gJiBoYW5kbGVyKCppKTsKCQlpZihoYW5kbGVyKSB7CgkJCWhhbmRsZXIoYXJndW1lbnQpOwoJCX0KCX0KfQpwcml2YXRlOgpzdGQ6Omxpc3Q8c3RkOjpmdW5jdGlvbjx2b2lkKEEpPj4gbUhhbmRsZXJzOyB9OwoKc3RydWN0IFNvbWVTZW5kZXIgewpTb21lU2VuZGVyKHN0ZDo6c3RyaW5nIGNvbnN0ICYgbmFtZSkgOiBtTmFtZShuYW1lKSB7IH0KSVg8c3RkOjpmdW5jdGlvbjx2b2lkKHN0ZDo6c3RyaW5nIGNvbnN0ICYpPj4gJiBPbk5hbWVDaGFuZ2VkKHZvaWQpIHsgcmV0dXJuIG1Pbk5hbWVDaGFuZ2VkOyB9CnZvaWQgQ2hhbmdlTmFtZShzdGQ6OnN0cmluZyBjb25zdCAmIG5hbWUpIHsgbU5hbWUgPSBuYW1lOyBtT25OYW1lQ2hhbmdlZC5GaXJlKG1OYW1lKTsgfQpwcml2YXRlOgpFdmVudDxzdGQ6OnN0cmluZyBjb25zdCAmPiBtT25OYW1lQ2hhbmdlZDsKc3RkOjpzdHJpbmcgbU5hbWU7Cn07CgoKCmludCBtYWluKHZvaWQpIHsKCVNvbWVTZW5kZXIgc3MoIkJvYiIpOwoJc3MuT25OYW1lQ2hhbmdlZCgpLkFkZEhhbmRsZXIoW10oc3RkOjpzdHJpbmcgY29uc3QgJiBuYW1lKSB7CgkJc3RkOjpjb3V0IDw8IG5hbWUgPDwgIiEiIDw8IHN0ZDo6ZW5kbDsKCX0pOwoJc3MuT25OYW1lQ2hhbmdlZCgpLkFkZEhhbmRsZXIoW10oc3RkOjpzdHJpbmcgY29uc3QgJiBuYW1lKSB7CgkJc3RkOjpjb3V0IDw8IG5hbWUgPDwgIj8iIDw8IHN0ZDo6ZW5kbDsKCX0pOwoJc3MuQ2hhbmdlTmFtZSgiQWxpY2UiKTsKLy8Jc3MuT25OYW1lQ2hhbmdlZCgpLkZpcmUoImhvZ2UiKTsKCXN0ZDo6Z2V0Y2hhcigpOwoJcmV0dXJuIDA7Cn0K