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::Ensure183a1c297aSPatrick 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 { 25*6050b655SMichal Orzel call(); 26f7ea2997SKrzysztof Grobelny } 27f7ea2997SKrzysztof Grobelny 28f7ea2997SKrzysztof Grobelny template <class U> operator =utils::Ensure29f7ea2997SKrzysztof Grobelny Ensure& operator=(U&& other) 30f7ea2997SKrzysztof Grobelny { 31*6050b655SMichal Orzel call(); 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 { 40*6050b655SMichal Orzel call(); 41*6050b655SMichal Orzel functor = std::nullopt; 42f7ea2997SKrzysztof Grobelny return *this; 43f7ea2997SKrzysztof Grobelny } 44f7ea2997SKrzysztof Grobelny 45f7ea2997SKrzysztof Grobelny Ensure& operator=(const Ensure&) = delete; 46f7ea2997SKrzysztof Grobelny operator boolutils::Ensure47973b4bb0SKrzysztof Grobelny explicit operator bool() const 48973b4bb0SKrzysztof Grobelny { 49973b4bb0SKrzysztof Grobelny return static_cast<bool>(functor); 50973b4bb0SKrzysztof Grobelny } 51973b4bb0SKrzysztof Grobelny 52f7ea2997SKrzysztof Grobelny private: callutils::Ensure53*6050b655SMichal Orzel void call() 54f7ea2997SKrzysztof Grobelny { 55f7ea2997SKrzysztof Grobelny if (functor) 56f7ea2997SKrzysztof Grobelny { 57f7ea2997SKrzysztof Grobelny (*functor)(); 58f7ea2997SKrzysztof Grobelny } 59f7ea2997SKrzysztof Grobelny } 60f7ea2997SKrzysztof Grobelny 61f7ea2997SKrzysztof Grobelny std::optional<F> functor; 62f7ea2997SKrzysztof Grobelny }; 63f7ea2997SKrzysztof Grobelny 64f7ea2997SKrzysztof Grobelny } // namespace utils 65