You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.7 KiB
96 lines
2.7 KiB
#ifndef MONOFORMAT_BITHELPERS_HPP
|
|
#define MONOFORMAT_BITHELPERS_HPP
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <climits>
|
|
#include <concepts>
|
|
|
|
namespace monoformat {
|
|
|
|
template<std::integral Int, std::integral OtherInt>
|
|
constexpr inline bool isBitSet(Int value, OtherInt bit) {
|
|
if (bit < 0 || bit >= static_cast<Int>(sizeof(Int) * CHAR_BIT)) [[unlikely]] {
|
|
return false;
|
|
}
|
|
|
|
Int mask = Int{1} << static_cast<Int>(bit);
|
|
return (value & mask) == mask;
|
|
}
|
|
|
|
template<std::integral OtherInt>
|
|
constexpr inline bool isBitSet(std::byte value, OtherInt bit) {
|
|
return isBitSet(static_cast<std::uint8_t>(value), bit);
|
|
}
|
|
|
|
template<std::integral Int, std::integral OtherInt>
|
|
constexpr inline void setBit(Int& value, OtherInt bit) {
|
|
if (bit < 0 || bit >= static_cast<Int>(sizeof(Int) * CHAR_BIT)) [[unlikely]] {
|
|
return;
|
|
}
|
|
|
|
Int mask = Int{1} << static_cast<Int>(bit);
|
|
value |= mask;
|
|
}
|
|
|
|
template<std::integral OtherInt>
|
|
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<std::uint8_t>(bit);
|
|
value = static_cast<std::byte>(static_cast<std::uint8_t>(value) | mask);
|
|
}
|
|
|
|
template<std::integral Int, std::integral OtherInt>
|
|
constexpr inline void unsetBit(Int& value, OtherInt bit) {
|
|
if (bit < 0 || bit >= static_cast<Int>(sizeof(Int) * CHAR_BIT)) [[unlikely]] {
|
|
return;
|
|
}
|
|
|
|
Int mask = Int{1} << static_cast<Int>(bit);
|
|
value &= ~mask;
|
|
}
|
|
|
|
template<std::integral OtherInt>
|
|
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<std::uint8_t>(bit);
|
|
value = static_cast<std::byte>(static_cast<std::uint8_t>(value) & ~mask);
|
|
}
|
|
|
|
template<std::integral Int, std::integral OtherInt>
|
|
constexpr inline void maybeSetBit(Int& value, OtherInt bit, bool set) {
|
|
if (bit < 0 || bit >= static_cast<Int>(sizeof(Int) * CHAR_BIT)) [[unlikely]] {
|
|
return;
|
|
}
|
|
|
|
Int mask = Int{1} << static_cast<Int>(bit);
|
|
if (set) {
|
|
value |= mask;
|
|
} else {
|
|
value &= ~mask;
|
|
}
|
|
}
|
|
|
|
template<std::integral OtherInt>
|
|
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<std::uint8_t>(bit);
|
|
if (set) {
|
|
value = static_cast<std::byte>(static_cast<std::uint8_t>(value) | mask);
|
|
} else {
|
|
value = static_cast<std::byte>(static_cast<std::uint8_t>(value) & ~mask);
|
|
}
|
|
}
|
|
|
|
} // namespace monoformat
|
|
|
|
#endif // MONOFORMAT_BITHELPERS_HPP
|
|
|