#pragma once #include #include namespace utils { template struct Ensure { Ensure() = default; template Ensure(U&& functor) : functor(std::forward(functor)) {} Ensure(F functor) : functor(std::move(functor)) {} Ensure(Ensure&& other) = delete; Ensure(const Ensure&) = delete; ~Ensure() { call(); } template Ensure& operator=(U&& other) { call(); functor = std::move(other); return *this; } Ensure& operator=(Ensure&& other) = delete; Ensure& operator=(std::nullptr_t) { call(); functor = std::nullopt; return *this; } Ensure& operator=(const Ensure&) = delete; explicit operator bool() const { return static_cast(functor); } private: void call() { if (functor) { (*functor)(); } } std::optional functor; }; } // namespace utils