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