xref: /openbmc/telemetry/src/state.hpp (revision 1cdd7e4f)
1 #pragma once
2 
3 #include <bitset>
4 
5 enum class ReportFlags
6 {
7     enabled,
8     valid
9 };
10 
11 enum class StateEvent
12 {
13     active,
14     inactive,
15     activated,
16     deactivated
17 };
18 
19 template <class T>
20 concept boolean = std::is_same_v<T, bool>;
21 
22 template <class Flags, class Object, Flags... Keys>
23 class State
24 {
25   public:
26     explicit State(Object& object) : object(object)
27     {}
28 
29     template <Flags... Indexes>
30     StateEvent set(boolean auto... values)
31     {
32         static_assert(sizeof...(Indexes) == sizeof...(values));
33 
34         const bool previous = flags.all();
35 
36         (flags.set(indexOf<0, Indexes, Keys...>(), values), ...);
37 
38         if (previous != flags.all())
39         {
40             if (flags.all())
41             {
42                 object.activate();
43                 return StateEvent::activated;
44             }
45             else
46             {
47                 object.deactivate();
48                 return StateEvent::deactivated;
49             }
50         }
51 
52         return flags.all() ? StateEvent::active : StateEvent::inactive;
53     }
54 
55     template <Flags Index>
56     bool get() const
57     {
58         return flags.test(indexOf<0, Index, Keys...>());
59     }
60 
61     bool isActive() const
62     {
63         return flags.all();
64     }
65 
66   private:
67     template <size_t Index, Flags flag, Flags it, Flags... list>
68     static constexpr size_t indexOf()
69     {
70         if constexpr (flag == it)
71         {
72             return Index;
73         }
74         else
75         {
76             return indexOf<Index + 1, flag, list...>();
77         }
78     }
79 
80     Object& object;
81     std::bitset<sizeof...(Keys)> flags{0};
82 };
83