mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 14:27:16 +00:00
Add: EnumBitSet class to safely use enum class values as a bitset.
This maintains type-safe enum values and type-safe masks, and avoids using undefined enum values.
This commit is contained in:
parent
bf6293a13f
commit
fdb3555147
@ -108,4 +108,93 @@ debug_inline constexpr void ToggleFlag(T &x, const T y)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum-as-bit-set wrapper.
|
||||
* Allows wrapping enum values as a bit set. Methods are loosely modelled on std::bitset.
|
||||
* @tparam Tenum Enum values to wrap.
|
||||
* @tparam Tsorage Storage type required to hold eenum values.
|
||||
*/
|
||||
template <typename Tenum, typename Tstorage>
|
||||
class EnumBitSet {
|
||||
public:
|
||||
using enum_type = Tenum; ///< Enum type of this EnumBitSet.
|
||||
using storage_type = Tstorage; ///< Storage type of this EnumBitSet.
|
||||
|
||||
constexpr EnumBitSet() : data(0) {}
|
||||
constexpr EnumBitSet(Tenum value) : data(0) { this->Set(value); }
|
||||
explicit constexpr EnumBitSet(Tstorage data) : data(data) {}
|
||||
|
||||
/**
|
||||
* Construct an EnumBitSet from a list of enum values.
|
||||
* @param values List of enum values.
|
||||
*/
|
||||
constexpr EnumBitSet(std::initializer_list<const Tenum> values) : data(0)
|
||||
{
|
||||
for (const Tenum &value : values) {
|
||||
this->Set(value);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto operator <=>(const EnumBitSet &) const noexcept = default;
|
||||
|
||||
/**
|
||||
* Set the enum value.
|
||||
* @param value Enum value to set.
|
||||
* @returns The EnumBitset
|
||||
*/
|
||||
inline constexpr EnumBitSet &Set(Tenum value)
|
||||
{
|
||||
this->data |= (1U << to_underlying(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the enum value to not set.
|
||||
* @param value Enum value to reset.
|
||||
* @returns The EnumBitset
|
||||
*/
|
||||
inline constexpr EnumBitSet &Reset(Tenum value)
|
||||
{
|
||||
this->data &= ~(1U << to_underlying(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip the enum value.
|
||||
* @param value Enum value to flip.
|
||||
* @returns The EnumBitset
|
||||
*/
|
||||
inline constexpr EnumBitSet &Flip(Tenum value)
|
||||
{
|
||||
if (this->Test(value)) {
|
||||
return this->Reset(value);
|
||||
} else {
|
||||
return this->Set(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the enum value is set.
|
||||
* @param value Enum value to check.
|
||||
* @returns true iff the requested value is set.
|
||||
*/
|
||||
inline constexpr bool Test(Tenum value) const
|
||||
{
|
||||
return (this->data & (1U << to_underlying(value))) != 0;
|
||||
}
|
||||
|
||||
inline constexpr EnumBitSet operator |(const EnumBitSet &other) const
|
||||
{
|
||||
return EnumBitSet{static_cast<Tstorage>(this->data | other.data)};
|
||||
}
|
||||
|
||||
inline constexpr EnumBitSet operator &(const EnumBitSet &other) const
|
||||
{
|
||||
return EnumBitSet{static_cast<Tstorage>(this->data & other.data)};
|
||||
}
|
||||
|
||||
private:
|
||||
Tstorage data; ///< Bitmask of enum values.
|
||||
};
|
||||
|
||||
#endif /* ENUM_TYPE_HPP */
|
||||
|
Loading…
Reference in New Issue
Block a user