blob: 91a7dafb436d2a254370166e65f7f2fe66cae666 [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:
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};