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