xref: /openbmc/telemetry/src/utils/ensure.hpp (revision f7ea2997)
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