#pragma once #if !defined(MIJIN_UTIL_BITFLAGS_HPP_INCLUDED) #define MIJIN_UTIL_BITFLAGS_HPP_INCLUDED 1 #include #include namespace mijin { // // public defines // // // public constants // // // public types // template struct BitFlags { using bits_t = TBits; constexpr TBits& operator |=(const BitFlags& other) { for (std::size_t idx = 0; idx < sizeof(TBits); ++idx) { *(std::bit_cast(asBits()) + idx) |= *(std::bit_cast(other.asBits()) + idx); } return *asBits(); } constexpr TBits& operator &=(const BitFlags& other) { for (std::size_t idx = 0; idx < sizeof(TBits); ++idx) { *(std::bit_cast(asBits()) + idx) &= *(std::bit_cast(other.asBits()) + idx); } return *asBits(); } constexpr TBits& operator ^=(const BitFlags& other) { for (std::size_t idx = 0; idx < sizeof(TBits); ++idx) { *(std::bit_cast(asBits()) + idx) ^= *(std::bit_cast(other.asBits()) + idx); } return *asBits(); } constexpr TBits operator& (const BitFlags& other) const { TBits copy(*asBits()); copy &= other; return copy; } constexpr TBits operator| (const BitFlags& other) const { TBits copy(*asBits()); copy |= other; return copy; } constexpr TBits operator^ (const BitFlags& other) const { TBits copy(*asBits()); copy ^= other; return copy; } explicit constexpr operator bool() const { for (std::size_t idx = 0; idx < sizeof(TBits); ++idx) { if (*(std::bit_cast(asBits()) + idx) != std::byte(0)) { return true; } } return false; } constexpr bool operator!() const { return !static_cast(*this); } auto operator<=>(const BitFlags&) const noexcept = default; private: constexpr TBits* asBits() { return static_cast(this); } constexpr const TBits* asBits() const { return static_cast(this); } }; template constexpr bool is_bitflags_v = std::is_base_of_v, T>; // // public functions // } // namespace mijin #endif // !defined(MIJIN_UTIL_BITFLAGS_HPP_INCLUDED)