blob: fedc8c571c00dd1697ac7d59a14435b34ac9cd40 [file] [log] [blame]
#pragma once
#include <bitset>
enum class ReportFlags
{
enabled,
valid
};
enum class StateEvent
{
active,
inactive,
activated,
deactivated
};
template <class T>
concept boolean = std::is_same_v<T, bool>;
template <class Flags, class Object, Flags... Keys>
class State
{
public:
explicit State(Object& object) : object(object) {}
template <Flags... Indexes>
StateEvent set(boolean auto... values)
{
static_assert(sizeof...(Indexes) == sizeof...(values));
const bool previous = flags.all();
(flags.set(indexOf<0, Indexes, Keys...>(), values), ...);
if (previous != flags.all())
{
if (flags.all())
{
object.activate();
return StateEvent::activated;
}
else
{
object.deactivate();
return StateEvent::deactivated;
}
}
return flags.all() ? StateEvent::active : StateEvent::inactive;
}
template <Flags Index>
bool get() const
{
return flags.test(indexOf<0, Index, Keys...>());
}
bool isActive() const
{
return flags.all();
}
private:
template <size_t Index, Flags flag, Flags it, Flags... list>
static constexpr size_t indexOf()
{
if constexpr (flag == it)
{
return Index;
}
else
{
return indexOf<Index + 1, flag, list...>();
}
}
Object& object;
std::bitset<sizeof...(Keys)> flags{0};
};