#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() { clear(); } template Ensure& operator=(U&& other) { clear(); functor = std::move(other); return *this; } Ensure& operator=(Ensure&& other) = delete; Ensure& operator=(std::nullptr_t) { clear(); return *this; } Ensure& operator=(const Ensure&) = delete; explicit operator bool() const { return static_cast(functor); } private: void clear() { if (functor) { (*functor)(); functor = std::nullopt; } } std::optional functor; }; } // namespace utils