#pragma once #include namespace jvalidate::detail { /** * @brief An object representing a cleanup function, to be called as if it was * a destructor for the current function scope. Similar to e.g. D-lang's * scope(exit) or @see https://en.cppreference.com/w/cpp/experimental/scope_exit * * Is movable - allowing us to return this scope object from its constructing * context into the actual owning context that wants to control that scope. */ class OnBlockExit { private: std::function callback_; public: OnBlockExit() = default; template OnBlockExit(F && callback) : callback_(callback) {} // Must be explicity implemented because function's move ctor is non-destructive OnBlockExit(OnBlockExit && other) { std::swap(other.callback_, callback_); } // Must be explicity implemented because function's move-assign is non-destructive OnBlockExit & operator=(OnBlockExit && other) { std::swap(other.callback_, callback_); return *this; } ~OnBlockExit() { if (callback_) { callback_(); } } }; }