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