xref: /openbmc/telemetry/src/utils/ensure.hpp (revision f7ea2997ae6b4fad0dc35f9afa9b488d774f2ee1)
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   private:
57     void clear()
58     {
59         if (functor)
60         {
61             (*functor)();
62             functor = std::nullopt;
63         }
64     }
65 
66     std::optional<F> functor;
67 };
68 
69 } // namespace utils
70