#ifndef MONOFORMAT_BITHELPERS_HPP #define MONOFORMAT_BITHELPERS_HPP #include #include #include #include namespace monoformat { template constexpr inline bool isBitSet(Int value, OtherInt bit) { if (bit < 0 || bit >= static_cast(sizeof(Int) * CHAR_BIT)) [[unlikely]] { return false; } Int mask = Int{1} << static_cast(bit); return (value & mask) == mask; } template constexpr inline bool isBitSet(std::byte value, OtherInt bit) { return isBitSet(static_cast(value), bit); } template constexpr inline void setBit(Int& value, OtherInt bit) { if (bit < 0 || bit >= static_cast(sizeof(Int) * CHAR_BIT)) [[unlikely]] { return; } Int mask = Int{1} << static_cast(bit); value |= mask; } template constexpr inline void setBit(std::byte& value, OtherInt bit) { if (bit < 0 || bit >= CHAR_BIT) [[unlikely]] { return; } std::uint8_t mask = std::uint8_t{1} << static_cast(bit); value = static_cast(static_cast(value) | mask); } template constexpr inline void unsetBit(Int& value, OtherInt bit) { if (bit < 0 || bit >= static_cast(sizeof(Int) * CHAR_BIT)) [[unlikely]] { return; } Int mask = Int{1} << static_cast(bit); value &= ~mask; } template constexpr inline void unsetBit(std::byte& value, OtherInt bit) { if (bit < 0 || bit >= CHAR_BIT) [[unlikely]] { return; } std::uint8_t mask = std::uint8_t{1} << static_cast(bit); value = static_cast(static_cast(value) & ~mask); } template constexpr inline void maybeSetBit(Int& value, OtherInt bit, bool set) { if (bit < 0 || bit >= static_cast(sizeof(Int) * CHAR_BIT)) [[unlikely]] { return; } Int mask = Int{1} << static_cast(bit); if (set) { value |= mask; } else { value &= ~mask; } } template constexpr inline void maybeSetBit(std::byte& value, OtherInt bit, bool set) { if (bit < 0 || bit >= CHAR_BIT) [[unlikely]] { return; } std::uint8_t mask = std::uint8_t{1} << static_cast(bit); if (set) { value = static_cast(static_cast(value) | mask); } else { value = static_cast(static_cast(value) & ~mask); } } } // namespace monoformat #endif // MONOFORMAT_BITHELPERS_HPP