1f7ea2997SKrzysztof Grobelny #pragma once 2f7ea2997SKrzysztof Grobelny 3f7ea2997SKrzysztof Grobelny #include <optional> 4f7ea2997SKrzysztof Grobelny #include <utility> 5f7ea2997SKrzysztof Grobelny 6f7ea2997SKrzysztof Grobelny namespace utils 7f7ea2997SKrzysztof Grobelny { 8f7ea2997SKrzysztof Grobelny 9f7ea2997SKrzysztof Grobelny template <class F> 10f7ea2997SKrzysztof Grobelny struct Ensure 11f7ea2997SKrzysztof Grobelny { 12f7ea2997SKrzysztof Grobelny Ensure() = default; 13f7ea2997SKrzysztof Grobelny 14f7ea2997SKrzysztof Grobelny template <class U> 15f7ea2997SKrzysztof Grobelny Ensure(U&& functor) : functor(std::forward<U>(functor)) 16f7ea2997SKrzysztof Grobelny {} 17f7ea2997SKrzysztof Grobelny 18f7ea2997SKrzysztof Grobelny Ensure(F functor) : functor(std::move(functor)) 19f7ea2997SKrzysztof Grobelny {} 20f7ea2997SKrzysztof Grobelny 21f7ea2997SKrzysztof Grobelny Ensure(Ensure&& other) : functor(std::move(other.functor)) 22f7ea2997SKrzysztof Grobelny { 23f7ea2997SKrzysztof Grobelny other.functor = std::nullopt; 24f7ea2997SKrzysztof Grobelny } 25f7ea2997SKrzysztof Grobelny 26f7ea2997SKrzysztof Grobelny Ensure(const Ensure&) = delete; 27f7ea2997SKrzysztof Grobelny 28f7ea2997SKrzysztof Grobelny ~Ensure() 29f7ea2997SKrzysztof Grobelny { 30f7ea2997SKrzysztof Grobelny clear(); 31f7ea2997SKrzysztof Grobelny } 32f7ea2997SKrzysztof Grobelny 33f7ea2997SKrzysztof Grobelny template <class U> 34f7ea2997SKrzysztof Grobelny Ensure& operator=(U&& other) 35f7ea2997SKrzysztof Grobelny { 36f7ea2997SKrzysztof Grobelny clear(); 37f7ea2997SKrzysztof Grobelny functor = std::move(other); 38f7ea2997SKrzysztof Grobelny return *this; 39f7ea2997SKrzysztof Grobelny } 40f7ea2997SKrzysztof Grobelny 41f7ea2997SKrzysztof Grobelny Ensure& operator=(Ensure&& other) 42f7ea2997SKrzysztof Grobelny { 43f7ea2997SKrzysztof Grobelny clear(); 44f7ea2997SKrzysztof Grobelny std::swap(functor, other.functor); 45f7ea2997SKrzysztof Grobelny return *this; 46f7ea2997SKrzysztof Grobelny } 47f7ea2997SKrzysztof Grobelny 48f7ea2997SKrzysztof Grobelny Ensure& operator=(std::nullptr_t) 49f7ea2997SKrzysztof Grobelny { 50f7ea2997SKrzysztof Grobelny clear(); 51f7ea2997SKrzysztof Grobelny return *this; 52f7ea2997SKrzysztof Grobelny } 53f7ea2997SKrzysztof Grobelny 54f7ea2997SKrzysztof Grobelny Ensure& operator=(const Ensure&) = delete; 55f7ea2997SKrzysztof Grobelny 56*973b4bb0SKrzysztof Grobelny explicit operator bool() const 57*973b4bb0SKrzysztof Grobelny { 58*973b4bb0SKrzysztof Grobelny return static_cast<bool>(functor); 59*973b4bb0SKrzysztof Grobelny } 60*973b4bb0SKrzysztof Grobelny 61f7ea2997SKrzysztof Grobelny private: 62f7ea2997SKrzysztof Grobelny void clear() 63f7ea2997SKrzysztof Grobelny { 64f7ea2997SKrzysztof Grobelny if (functor) 65f7ea2997SKrzysztof Grobelny { 66f7ea2997SKrzysztof Grobelny (*functor)(); 67f7ea2997SKrzysztof Grobelny functor = std::nullopt; 68f7ea2997SKrzysztof Grobelny } 69f7ea2997SKrzysztof Grobelny } 70f7ea2997SKrzysztof Grobelny 71f7ea2997SKrzysztof Grobelny std::optional<F> functor; 72f7ea2997SKrzysztof Grobelny }; 73f7ea2997SKrzysztof Grobelny 74f7ea2997SKrzysztof Grobelny } // namespace utils 75