#include <iostream>
template<typename T>
class Deleter
{
T x;
public:
inline Deleter( const T functor ): x(functor) { };
inline ~Deleter() { x(); };
};
template<typename T>
inline Deleter<T> finally( const T x )
{
return Deleter<T>(x);
};
#define FINALLY_IMPL(line, code) auto deleter##line = finally( [&]() { code; } );
#define FINALLY(code) FINALLY_IMPL(__LINE__, code)
class Test
{
private:
int code;
public:
Test(int c): code(c) { std::cout << "Test(" << code << ");\n"; };
~Test() { std::cout << "~Test(" << code << ");\n"; };
void method() { std::cout << "method(" << code << ")\n"; };
};
void func()
{
Test *x = nullptr;
FINALLY(
delete x;
);
{
Test *y = nullptr;
FINALLY(
delete y;
);
y = new Test(1);
y->method();
};
x = new Test(2);
x->method();
};
int main(int argc, char *argv[])
{
func();
std::cout << "ok\n";
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgRGVsZXRlcgp7CiAgICAgICAgVCB4OwpwdWJsaWM6CiAgICAgICAgaW5saW5lIERlbGV0ZXIoIGNvbnN0IFQgZnVuY3RvciApOiB4KGZ1bmN0b3IpIHsgfTsKICAgICAgICBpbmxpbmUgfkRlbGV0ZXIoKSB7IHgoKTsgfTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmlubGluZSBEZWxldGVyPFQ+IGZpbmFsbHkoIGNvbnN0IFQgeCApCnsKICAgICAgICByZXR1cm4gRGVsZXRlcjxUPih4KTsKfTsKCiNkZWZpbmUgRklOQUxMWV9JTVBMKGxpbmUsIGNvZGUpIGF1dG8gZGVsZXRlciMjbGluZSA9IGZpbmFsbHkoIFsmXSgpIHsgY29kZTsgfSApOwojZGVmaW5lIEZJTkFMTFkoY29kZSkgRklOQUxMWV9JTVBMKF9fTElORV9fLCBjb2RlKQoKY2xhc3MgVGVzdAp7CnByaXZhdGU6CiAgICAgICAgaW50IGNvZGU7CnB1YmxpYzoKICAgICAgICBUZXN0KGludCBjKTogY29kZShjKSB7IHN0ZDo6Y291dCA8PCAiVGVzdCgiIDw8IGNvZGUgPDwgIik7XG4iOyB9OwogICAgICAgIH5UZXN0KCkgeyBzdGQ6OmNvdXQgPDwgIn5UZXN0KCIgPDwgY29kZSA8PCAiKTtcbiI7IH07CiAgICAgICAgdm9pZCBtZXRob2QoKSB7IHN0ZDo6Y291dCA8PCAibWV0aG9kKCIgPDwgY29kZSA8PCAiKVxuIjsgfTsKfTsKCnZvaWQgZnVuYygpCnsKICAgICAgICBUZXN0ICp4ID0gbnVsbHB0cjsKICAgICAgICBGSU5BTExZKAogICAgICAgICAgICAgICAgZGVsZXRlIHg7CiAgICAgICAgKTsKCiAgICAgICAgewogICAgICAgICAgICAgICAgVGVzdCAqeSA9IG51bGxwdHI7CiAgICAgICAgICAgICAgICBGSU5BTExZKAogICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgeTsKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB5ID0gbmV3IFRlc3QoMSk7CiAgICAgICAgICAgICAgICB5LT5tZXRob2QoKTsKICAgICAgICB9OwogICAgICAgIHggPSBuZXcgVGVzdCgyKTsKICAgICAgICB4LT5tZXRob2QoKTsKfTsKCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIAp7CiAgICAgICAgZnVuYygpOwogICAgICAgIHN0ZDo6Y291dCA8PCAib2tcbiI7CiAgICAgICAgcmV0dXJuIDA7Cn0=