metaforce/Runtime/Flags.hpp

71 lines
1.9 KiB
C++

#pragma once
#include <type_traits>
namespace metaforce {
template <typename BitType>
class Flags {
public:
using MaskType = std::underlying_type_t<BitType>;
// constructors
constexpr Flags() noexcept : m_mask(0) {}
constexpr Flags(BitType bit) noexcept : m_mask(static_cast<MaskType>(bit)) {}
constexpr Flags(Flags<BitType> const& rhs) noexcept : m_mask(rhs.m_mask) {}
constexpr explicit Flags(MaskType flags) noexcept : m_mask(flags) {}
[[nodiscard]] constexpr bool IsSet(Flags<BitType> const bit) const noexcept { return bool(*this & bit); }
// relational operators
bool operator==(Flags<BitType> const& rhs) const noexcept { return m_mask == rhs.m_mask; }
// logical operator
constexpr bool operator!() const noexcept { return !m_mask; }
// bitwise operators
constexpr Flags<BitType> operator&(Flags<BitType> const& rhs) const noexcept {
return Flags<BitType>(m_mask & rhs.m_mask);
}
constexpr Flags<BitType> operator|(Flags<BitType> const& rhs) const noexcept {
return Flags<BitType>(m_mask | rhs.m_mask);
}
constexpr Flags<BitType> operator^(Flags<BitType> const& rhs) const noexcept {
return Flags<BitType>(m_mask ^ rhs.m_mask);
}
// assignment operators
constexpr Flags<BitType>& operator=(Flags<BitType> const& rhs) noexcept {
m_mask = rhs.m_mask;
return *this;
}
constexpr Flags<BitType>& operator|=(Flags<BitType> const& rhs) noexcept {
m_mask |= rhs.m_mask;
return *this;
}
constexpr Flags<BitType>& operator&=(Flags<BitType> const& rhs) noexcept {
m_mask &= rhs.m_mask;
return *this;
}
constexpr Flags<BitType>& operator^=(Flags<BitType> const& rhs) noexcept {
m_mask ^= rhs.m_mask;
return *this;
}
// cast operators
explicit constexpr operator bool() const noexcept { return m_mask != 0; }
explicit constexpr operator MaskType() const noexcept { return m_mask; }
private:
MaskType m_mask;
};
} // namespace metaforce