#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>
using namespace std;
template<class F> class ScopeGuard
{
private:
F f;
bool active;
public:
ScopeGuard(F f) :f(::std::move(f)), active(true) {}
ScopeGuard(ScopeGuard&& rhs) :f(::std::move(rhs.f)), active(rhs.active) { rhs.dismiss();}
~ScopeGuard() { if (active) f(); }
void dismiss() { active = false; }
ScopeGuard() = delete;
ScopeGuard(const ScopeGuard&) = delete;
ScopeGuard& operator=(const ScopeGuard&) = delete;
};
template<class FF> static ScopeGuard<FF> makeScopeGuard(FF f) { return ScopeGuard<FF>(f); }
#define CONCAT_IMPL(s1, s2) s1##s2
#define CONCAT(s1, s2) CONCAT_IMPL(s1, s2)
#define SCOPE_GUARD(lambda) \
auto CONCAT(scope_guard_, __LINE__)(makeScopeGuard(lambda)); \
(void)CONCAT(scope_guard_, __LINE__);
void scopeExit(const string& name)
{
cout << "Exiting " << name << " scope "
<< (uncaught_exception() ? "(there was an exception)" : "(no exception)") << endl;
}
int main()
{
SCOPE_GUARD([](){ scopeExit("main"); })
try
{
SCOPE_GUARD([](){ scopeExit("try"); })
throw runtime_error("Spectacular failure!");
}
catch (const exception& e)
{
cout << e.what() << endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8ZXhjZXB0aW9uPgojaW5jbHVkZSA8c3RkZXhjZXB0Pgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCnRlbXBsYXRlPGNsYXNzIEY+IGNsYXNzIFNjb3BlR3VhcmQKewpwcml2YXRlOgoJRiBmOwoJYm9vbCBhY3RpdmU7CnB1YmxpYzoKCVNjb3BlR3VhcmQoRiBmKSA6Zig6OnN0ZDo6bW92ZShmKSksIGFjdGl2ZSh0cnVlKSB7fQoJU2NvcGVHdWFyZChTY29wZUd1YXJkJiYgcmhzKSA6Zig6OnN0ZDo6bW92ZShyaHMuZikpLCBhY3RpdmUocmhzLmFjdGl2ZSkgeyByaHMuZGlzbWlzcygpO30KCX5TY29wZUd1YXJkKCkgeyBpZiAoYWN0aXZlKSBmKCk7IH0KCgl2b2lkIGRpc21pc3MoKSB7IGFjdGl2ZSA9IGZhbHNlOyB9CgoJU2NvcGVHdWFyZCgpID0gZGVsZXRlOwoJU2NvcGVHdWFyZChjb25zdCBTY29wZUd1YXJkJikgPSBkZWxldGU7CglTY29wZUd1YXJkJiBvcGVyYXRvcj0oY29uc3QgU2NvcGVHdWFyZCYpID0gZGVsZXRlOwp9OwoKdGVtcGxhdGU8Y2xhc3MgRkY+IHN0YXRpYyBTY29wZUd1YXJkPEZGPiBtYWtlU2NvcGVHdWFyZChGRiBmKSB7IHJldHVybiBTY29wZUd1YXJkPEZGPihmKTsgfQoKI2RlZmluZSBDT05DQVRfSU1QTChzMSwgczIpIHMxIyNzMgojZGVmaW5lIENPTkNBVChzMSwgczIpIENPTkNBVF9JTVBMKHMxLCBzMikKCiNkZWZpbmUgU0NPUEVfR1VBUkQobGFtYmRhKSBcCiAgYXV0byBDT05DQVQoc2NvcGVfZ3VhcmRfLCBfX0xJTkVfXykobWFrZVNjb3BlR3VhcmQobGFtYmRhKSk7IFwKICAodm9pZClDT05DQVQoc2NvcGVfZ3VhcmRfLCBfX0xJTkVfXyk7CgoKdm9pZCBzY29wZUV4aXQoY29uc3Qgc3RyaW5nJiBuYW1lKQp7Cgljb3V0IDw8ICJFeGl0aW5nICIgPDwgbmFtZSA8PCAiIHNjb3BlICIKCSAgICAgPDwgKHVuY2F1Z2h0X2V4Y2VwdGlvbigpID8gIih0aGVyZSB3YXMgYW4gZXhjZXB0aW9uKSIgOiAiKG5vIGV4Y2VwdGlvbikiKSA8PCBlbmRsOwp9CgppbnQgbWFpbigpCnsKCVNDT1BFX0dVQVJEKFtdKCl7IHNjb3BlRXhpdCgibWFpbiIpOyB9KQoKCXRyeQoJewoJCVNDT1BFX0dVQVJEKFtdKCl7IHNjb3BlRXhpdCgidHJ5Iik7IH0pCgkJdGhyb3cgcnVudGltZV9lcnJvcigiU3BlY3RhY3VsYXIgZmFpbHVyZSEiKTsKCX0KCWNhdGNoIChjb25zdCBleGNlcHRpb24mIGUpCgl7CgkJY291dCA8PCBlLndoYXQoKSA8PCBlbmRsOwoJfQoKCXJldHVybiAwOwp9Cg==