1 #pragma once 2 3 #include <optional> 4 #include <utility> 5 6 namespace utils 7 { 8 9 template <class F> 10 struct Ensure 11 { 12 Ensure() = default; 13 14 template <class U> Ensureutils::Ensure15 Ensure(U&& functor) : functor(std::forward<U>(functor)) 16 {} 17 Ensureutils::Ensure18 Ensure(F functor) : functor(std::move(functor)) {} 19 20 Ensure(Ensure&& other) = delete; 21 Ensure(const Ensure&) = delete; 22 ~Ensureutils::Ensure23 ~Ensure() 24 { 25 clear(); 26 } 27 28 template <class U> operator =utils::Ensure29 Ensure& operator=(U&& other) 30 { 31 clear(); 32 functor = std::move(other); 33 return *this; 34 } 35 36 Ensure& operator=(Ensure&& other) = delete; 37 operator =utils::Ensure38 Ensure& operator=(std::nullptr_t) 39 { 40 clear(); 41 return *this; 42 } 43 44 Ensure& operator=(const Ensure&) = delete; 45 operator boolutils::Ensure46 explicit operator bool() const 47 { 48 return static_cast<bool>(functor); 49 } 50 51 private: clearutils::Ensure52 void clear() 53 { 54 if (functor) 55 { 56 (*functor)(); 57 functor = std::nullopt; 58 } 59 } 60 61 std::optional<F> functor; 62 }; 63 64 } // namespace utils 65