mijin2/source/mijin/util/bitflags.hpp

98 lines
2.3 KiB
C++

#pragma once
#if !defined(MIJIN_UTIL_BITFLAGS_HPP_INCLUDED)
#define MIJIN_UTIL_BITFLAGS_HPP_INCLUDED 1
#include <bit>
#include <cstddef>
namespace mijin
{
//
// public defines
//
//
// public constants
//
//
// public types
//
template<typename TBits>
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<std::byte*>(asBits()) + idx) |= *(std::bit_cast<const std::byte*>(other.asBits()) + idx);
}
return *asBits();
}
constexpr TBits& operator &=(const BitFlags& other) {
for (std::size_t idx = 0; idx < sizeof(TBits); ++idx) {
*(std::bit_cast<std::byte*>(asBits()) + idx) &= *(std::bit_cast<const std::byte*>(other.asBits()) + idx);
}
return *asBits();
}
constexpr TBits& operator ^=(const BitFlags& other) {
for (std::size_t idx = 0; idx < sizeof(TBits); ++idx) {
*(std::bit_cast<std::byte*>(asBits()) + idx) ^= *(std::bit_cast<const std::byte*>(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<const std::byte*>(asBits()) + idx) != std::byte(0)) {
return true;
}
}
return false;
}
constexpr bool operator!() const {
return !static_cast<bool>(*this);
}
private:
constexpr TBits* asBits() { return static_cast<TBits*>(this); }
constexpr const TBits* asBits() const { return static_cast<const TBits*>(this); }
};
template<typename T>
constexpr bool is_bitflags_v = std::is_base_of_v<BitFlags<T>, T>;
//
// public functions
//
} // namespace mijin
#endif // !defined(MIJIN_UTIL_BITFLAGS_HPP_INCLUDED)