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