#include <iostream>
#include <utility>
#define PP_CAT(a, b) PP_CAT_I(a, b)
#define PP_CAT_I(a, b) a ## b
// 普通はいらない
template<typename F>
struct scope_exit_t {
scope_exit_t(F & f) : f(f) {}
~scope_exit_t() { std::cout << "by lvalue: "; f(); }
private:
F & f;
};
template<typename F>
struct scope_exit_t<F&&> {
scope_exit_t(F && f) : f(f) {}
~scope_exit_t() { std::cout << "by rvalue: "; f(); }
private:
F f;
};
struct scope_exit_helper {
template<typename F>
scope_exit_t<F&&> operator->*(F && f) const {
return scope_exit_t<F&&>(std::forward<F>(f));
}
};
#define scope_exit auto PP_CAT(scope_exit_, __LINE__) = scope_exit_helper() ->* [&] ()
int main() {
scope_exit { std::cout << "hogehoge\n"; };
scope_exit { std::cout << "piyopiyo\n"; };
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KCiNkZWZpbmUgUFBfQ0FUKGEsIGIpIFBQX0NBVF9JKGEsIGIpCiNkZWZpbmUgUFBfQ0FUX0koYSwgYikgYSAjIyBiCgovLyDmma7pgJrjga/jgYTjgonjgarjgYQKdGVtcGxhdGU8dHlwZW5hbWUgRj4Kc3RydWN0IHNjb3BlX2V4aXRfdCB7CiAgICBzY29wZV9leGl0X3QoRiAmIGYpIDogZihmKSB7fQogICAgfnNjb3BlX2V4aXRfdCgpIHsgc3RkOjpjb3V0IDw8ICJieSBsdmFsdWU6ICI7IGYoKTsgfQpwcml2YXRlOgogICAgRiAmIGY7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGPgpzdHJ1Y3Qgc2NvcGVfZXhpdF90PEYmJj4gewogICAgc2NvcGVfZXhpdF90KEYgJiYgZikgOiBmKGYpIHt9CiAgICB+c2NvcGVfZXhpdF90KCkgeyBzdGQ6OmNvdXQgPDwgImJ5IHJ2YWx1ZTogIjsgZigpOyB9CnByaXZhdGU6CiAgICBGIGY7Cn07CgpzdHJ1Y3Qgc2NvcGVfZXhpdF9oZWxwZXIgewogICAgdGVtcGxhdGU8dHlwZW5hbWUgRj4KICAgIHNjb3BlX2V4aXRfdDxGJiY+IG9wZXJhdG9yLT4qKEYgJiYgZikgY29uc3QgewogICAgICAgIHJldHVybiBzY29wZV9leGl0X3Q8RiYmPihzdGQ6OmZvcndhcmQ8Rj4oZikpOwogICAgfQp9OwoKI2RlZmluZSBzY29wZV9leGl0IGF1dG8gUFBfQ0FUKHNjb3BlX2V4aXRfLCBfX0xJTkVfXykgPSBzY29wZV9leGl0X2hlbHBlcigpIC0+KiBbJl0gKCkKCmludCBtYWluKCkgewogICAgc2NvcGVfZXhpdCB7IHN0ZDo6Y291dCA8PCAiaG9nZWhvZ2VcbiI7IH07CiAgICBzY29wZV9leGl0IHsgc3RkOjpjb3V0IDw8ICJwaXlvcGl5b1xuIjsgfTsKfQo=