// SPDX-FileCopyrightText: 2015 Marek Rusinowski // SPDX-License-Identifier: MIT #include #include template class defer_finalizer { F f; bool moved; public: template defer_finalizer(T && f_) : f(std::forward(f_)), moved(false) { } defer_finalizer(const defer_finalizer &) = delete; defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) { other.moved = true; } ~defer_finalizer() { if (!moved) f(); } }; struct { template defer_finalizer operator<<(F && f) { return defer_finalizer(std::forward(f)); } } deferrer; #define TOKENPASTE(x, y) x ## y #define TOKENPASTE2(x, y) TOKENPASTE(x, y) #define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&] void f() { FILE *f = fopen("asdasd", "r"); defer { fclose(f); }; } // Compiler optimizes it nicely: http://goo.gl/XAGl6A