xref: /openbmc/telemetry/src/state.hpp (revision 3a1c297a36bcd78d33ee45c603cb1b46e4619f49)
1973b4bb0SKrzysztof Grobelny #pragma once
2973b4bb0SKrzysztof Grobelny 
3973b4bb0SKrzysztof Grobelny #include <bitset>
4973b4bb0SKrzysztof Grobelny 
5973b4bb0SKrzysztof Grobelny enum class ReportFlags
6973b4bb0SKrzysztof Grobelny {
7973b4bb0SKrzysztof Grobelny     enabled,
8973b4bb0SKrzysztof Grobelny     valid
9973b4bb0SKrzysztof Grobelny };
10973b4bb0SKrzysztof Grobelny 
11973b4bb0SKrzysztof Grobelny enum class StateEvent
12973b4bb0SKrzysztof Grobelny {
13973b4bb0SKrzysztof Grobelny     active,
14973b4bb0SKrzysztof Grobelny     inactive,
15973b4bb0SKrzysztof Grobelny     activated,
16973b4bb0SKrzysztof Grobelny     deactivated
17973b4bb0SKrzysztof Grobelny };
18973b4bb0SKrzysztof Grobelny 
19973b4bb0SKrzysztof Grobelny template <class T>
20973b4bb0SKrzysztof Grobelny concept boolean = std::is_same_v<T, bool>;
21973b4bb0SKrzysztof Grobelny 
22973b4bb0SKrzysztof Grobelny template <class Flags, class Object, Flags... Keys>
23973b4bb0SKrzysztof Grobelny class State
24973b4bb0SKrzysztof Grobelny {
25973b4bb0SKrzysztof Grobelny   public:
State(Object & object)26*3a1c297aSPatrick Williams     explicit State(Object& object) : object(object) {}
27973b4bb0SKrzysztof Grobelny 
28973b4bb0SKrzysztof Grobelny     template <Flags... Indexes>
set(boolean auto...values)29973b4bb0SKrzysztof Grobelny     StateEvent set(boolean auto... values)
30973b4bb0SKrzysztof Grobelny     {
31973b4bb0SKrzysztof Grobelny         static_assert(sizeof...(Indexes) == sizeof...(values));
32973b4bb0SKrzysztof Grobelny 
33973b4bb0SKrzysztof Grobelny         const bool previous = flags.all();
34973b4bb0SKrzysztof Grobelny 
35973b4bb0SKrzysztof Grobelny         (flags.set(indexOf<0, Indexes, Keys...>(), values), ...);
36973b4bb0SKrzysztof Grobelny 
37973b4bb0SKrzysztof Grobelny         if (previous != flags.all())
38973b4bb0SKrzysztof Grobelny         {
39973b4bb0SKrzysztof Grobelny             if (flags.all())
40973b4bb0SKrzysztof Grobelny             {
41973b4bb0SKrzysztof Grobelny                 object.activate();
42973b4bb0SKrzysztof Grobelny                 return StateEvent::activated;
43973b4bb0SKrzysztof Grobelny             }
44973b4bb0SKrzysztof Grobelny             else
45973b4bb0SKrzysztof Grobelny             {
46973b4bb0SKrzysztof Grobelny                 object.deactivate();
47973b4bb0SKrzysztof Grobelny                 return StateEvent::deactivated;
48973b4bb0SKrzysztof Grobelny             }
49973b4bb0SKrzysztof Grobelny         }
50973b4bb0SKrzysztof Grobelny 
51973b4bb0SKrzysztof Grobelny         return flags.all() ? StateEvent::active : StateEvent::inactive;
52973b4bb0SKrzysztof Grobelny     }
53973b4bb0SKrzysztof Grobelny 
54973b4bb0SKrzysztof Grobelny     template <Flags Index>
get() const55973b4bb0SKrzysztof Grobelny     bool get() const
56973b4bb0SKrzysztof Grobelny     {
57973b4bb0SKrzysztof Grobelny         return flags.test(indexOf<0, Index, Keys...>());
58973b4bb0SKrzysztof Grobelny     }
59973b4bb0SKrzysztof Grobelny 
isActive() const60973b4bb0SKrzysztof Grobelny     bool isActive() const
61973b4bb0SKrzysztof Grobelny     {
62973b4bb0SKrzysztof Grobelny         return flags.all();
63973b4bb0SKrzysztof Grobelny     }
64973b4bb0SKrzysztof Grobelny 
65973b4bb0SKrzysztof Grobelny   private:
66973b4bb0SKrzysztof Grobelny     template <size_t Index, Flags flag, Flags it, Flags... list>
indexOf()67973b4bb0SKrzysztof Grobelny     static constexpr size_t indexOf()
68973b4bb0SKrzysztof Grobelny     {
69973b4bb0SKrzysztof Grobelny         if constexpr (flag == it)
70973b4bb0SKrzysztof Grobelny         {
71973b4bb0SKrzysztof Grobelny             return Index;
72973b4bb0SKrzysztof Grobelny         }
73973b4bb0SKrzysztof Grobelny         else
74973b4bb0SKrzysztof Grobelny         {
75973b4bb0SKrzysztof Grobelny             return indexOf<Index + 1, flag, list...>();
76973b4bb0SKrzysztof Grobelny         }
77973b4bb0SKrzysztof Grobelny     }
78973b4bb0SKrzysztof Grobelny 
79973b4bb0SKrzysztof Grobelny     Object& object;
80973b4bb0SKrzysztof Grobelny     std::bitset<sizeof...(Keys)> flags{0};
81973b4bb0SKrzysztof Grobelny };
82