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> Ensureutils::Ensure15f7ea2997SKrzysztof Grobelny Ensure(U&& functor) : functor(std::forward<U>(functor)) 16f7ea2997SKrzysztof Grobelny {} 17f7ea2997SKrzysztof Grobelny Ensureutils::Ensure18*3a1c297aSPatrick Williams Ensure(F functor) : functor(std::move(functor)) {} 19f7ea2997SKrzysztof Grobelny 20bcf045a4SSzymon Dompke Ensure(Ensure&& other) = delete; 21f7ea2997SKrzysztof Grobelny Ensure(const Ensure&) = delete; 22f7ea2997SKrzysztof Grobelny ~Ensureutils::Ensure23f7ea2997SKrzysztof Grobelny ~Ensure() 24f7ea2997SKrzysztof Grobelny { 25f7ea2997SKrzysztof Grobelny clear(); 26f7ea2997SKrzysztof Grobelny } 27f7ea2997SKrzysztof Grobelny 28f7ea2997SKrzysztof Grobelny template <class U> operator =utils::Ensure29f7ea2997SKrzysztof Grobelny Ensure& operator=(U&& other) 30f7ea2997SKrzysztof Grobelny { 31f7ea2997SKrzysztof Grobelny clear(); 32f7ea2997SKrzysztof Grobelny functor = std::move(other); 33f7ea2997SKrzysztof Grobelny return *this; 34f7ea2997SKrzysztof Grobelny } 35f7ea2997SKrzysztof Grobelny 36bcf045a4SSzymon Dompke Ensure& operator=(Ensure&& other) = delete; 37f7ea2997SKrzysztof Grobelny operator =utils::Ensure38f7ea2997SKrzysztof Grobelny Ensure& operator=(std::nullptr_t) 39f7ea2997SKrzysztof Grobelny { 40f7ea2997SKrzysztof Grobelny clear(); 41f7ea2997SKrzysztof Grobelny return *this; 42f7ea2997SKrzysztof Grobelny } 43f7ea2997SKrzysztof Grobelny 44f7ea2997SKrzysztof Grobelny Ensure& operator=(const Ensure&) = delete; 45f7ea2997SKrzysztof Grobelny operator boolutils::Ensure46973b4bb0SKrzysztof Grobelny explicit operator bool() const 47973b4bb0SKrzysztof Grobelny { 48973b4bb0SKrzysztof Grobelny return static_cast<bool>(functor); 49973b4bb0SKrzysztof Grobelny } 50973b4bb0SKrzysztof Grobelny 51f7ea2997SKrzysztof Grobelny private: clearutils::Ensure52f7ea2997SKrzysztof Grobelny void clear() 53f7ea2997SKrzysztof Grobelny { 54f7ea2997SKrzysztof Grobelny if (functor) 55f7ea2997SKrzysztof Grobelny { 56f7ea2997SKrzysztof Grobelny (*functor)(); 57f7ea2997SKrzysztof Grobelny functor = std::nullopt; 58f7ea2997SKrzysztof Grobelny } 59f7ea2997SKrzysztof Grobelny } 60f7ea2997SKrzysztof Grobelny 61f7ea2997SKrzysztof Grobelny std::optional<F> functor; 62f7ea2997SKrzysztof Grobelny }; 63f7ea2997SKrzysztof Grobelny 64f7ea2997SKrzysztof Grobelny } // namespace utils 65