10#ifndef BITMATH_FUNC_HPP
11#define BITMATH_FUNC_HPP
32debug_inline
constexpr static uint
GB(
const T x,
const uint8_t s,
const uint8_t n)
34 return (x >> s) & (((T)1U << n) - 1);
57template <
typename T,
typename U>
58constexpr T
SB(T &x,
const uint8_t s,
const uint8_t n,
const U d)
60 x &= (T)(~((((T)1U << n) - 1) << s));
82template <
typename T,
typename U>
83constexpr T
AB(T &x,
const uint8_t s,
const uint8_t n,
const U i)
85 const T mask = ((((T)1U << n) - 1) << s);
86 x = (T)((x & ~mask) | ((x + (i << s)) & mask));
103debug_inline
constexpr bool HasBit(
const T x,
const uint8_t y)
105 return (x & ((T)1U << y)) != 0;
123 return x = (T)(x | ((T)1U << y));
136#define SETBITS(x, y) ((x) |= (y))
153 return x = (T)(x & ~((T)1U << y));
166#define CLRBITS(x, y) ((x) &= ~(y))
183 return x = (T)(x ^ ((T)1U << y));
202 return SB<T>(x, y, 1, value ? 1 : 0);
215 if (x == 0)
return 0;
217 if constexpr (std::is_enum_v<T>) {
218 return std::countr_zero<std::underlying_type_t<T>>(x);
220 return std::countr_zero(x);
234 if (x == 0)
return 0;
236 return std::numeric_limits<T>::digits - std::countl_zero(x) - 1;
252 return value &= (T)(value - 1);
264 if constexpr (std::is_enum_v<T>) {
265 return std::popcount<std::underlying_type_t<T>>(value);
267 return std::popcount(value);
280 return value != 0 && (value & (value - 1)) == 0;
292 return (value & (value - 1)) == 0;
300template <
typename Tbitpos = u
int,
typename Tbitset = u
int>
303 typedef Tbitpos value_type;
304 typedef value_type *pointer;
305 typedef value_type &reference;
306 typedef size_t difference_type;
307 typedef std::forward_iterator_tag iterator_category;
309 explicit Iterator(Tbitset bitset) : bitset(bitset), bitpos(
static_cast<Tbitpos
>(0))
314 bool operator==(
const Iterator &other)
const
316 return this->bitset == other.bitset;
318 bool operator!=(
const Iterator &other)
const {
return !(*
this == other); }
319 Tbitpos operator*()
const {
return this->bitpos; }
320 Iterator & operator++() { this->Next(); this->Validate();
return *
this; }
327 if (this->bitset != 0) {
328 typename std::make_unsigned<Tbitset>::type unsigned_value = this->bitset;
329 this->bitpos =
static_cast<Tbitpos
>(
FindFirstBit(unsigned_value));
339 Iterator begin() {
return Iterator(this->bitset); }
340 Iterator end() {
return Iterator(
static_cast<Tbitset
>(0)); }
341 bool empty() {
return this->begin() == this->end(); }
347#if defined(__APPLE__)
352# define BSWAP32(x) (static_cast<uint32_t>(CFSwapInt32(x)))
353# define BSWAP16(x) (static_cast<uint16_t>(CFSwapInt16(x)))
354#elif defined(_MSC_VER)
356# define BSWAP32(x) (_byteswap_ulong(x))
357# define BSWAP16(x) (_byteswap_ushort(x))
366#if !defined(__ICC) && defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ >= 3))
368 return static_cast<uint32_t
>(__builtin_bswap32(
static_cast<int32_t
>(x)));
370 return ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000) | ((x << 24) & 0xFF000000);
381 return (x >> 8) | (x << 8);
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr bool HasExactlyOneBit(T value)
Test whether value has exactly 1 bit set.
constexpr T AssignBit(T &x, const uint8_t y, bool value)
Assigns a bit in a variable.
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
constexpr uint8_t FindLastBit(T x)
Search the last set bit in a value.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
static uint32_t BSWAP32(uint32_t x)
Perform a 32 bits endianness bitswap on x.
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
constexpr bool HasAtMostOneBit(T value)
Test whether value has at most 1 bit set.
constexpr T AB(T &x, const uint8_t s, const uint8_t n, const U i)
Add i to n bits of x starting at bit s.
static uint16_t BSWAP16(uint16_t x)
Perform a 16 bits endianness bitswap on x.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T ToggleBit(T &x, const uint8_t y)
Toggles a bit in a variable.
constexpr T KillFirstBit(T value)
Clear the first bit in an integer.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Iterable ensemble of each set bit in a value.