Bit Manipulation & Integer Powers of Two
include/math/bit.h View source View on GitHubFunctions
Section titled “Functions”popcount
Section titled “popcount”cc_constfn size_t popcount(size_t n) source cc_constfn uint8_t ilog2(uint64_t x) source cc_constfn size_t pow2(size_t n) source next_pow2
Section titled “next_pow2”cc_constfn size_t next_pow2(size_t x) source prev_pow2
Section titled “prev_pow2”cc_constfn size_t prev_pow2(size_t x) source Macros
Section titled “Macros”#define BIT(n) source Must be a plain expression, not a statement, due to use in enums and whatnot
Expansion
#define BIT(n) (1ull << (n)) BITS_PER_BYTE
Section titled “BITS_PER_BYTE”#define BITS_PER_BYTE (8) source BIT_SIZEOF
Section titled “BIT_SIZEOF”#define BIT_SIZEOF(t) source Expansion
#define BIT_SIZEOF(t) (sizeof(t) * BITS_PER_BYTE) BIT_OFFSETOF
Section titled “BIT_OFFSETOF”#define BIT_OFFSETOF(s, m) source Expansion
#define BIT_OFFSETOF(s, m) (offsetof(s, m) * BITS_PER_BYTE) BIT_ALIGNOF
Section titled “BIT_ALIGNOF”#define BIT_ALIGNOF(s, m) source Expansion
#define BIT_ALIGNOF(s, m) (cc_alignof(s, m) * BITS_PER_BYTE) __bit_index_ok
Section titled “__bit_index_ok”#define __bit_index_ok(n, bits) source Verify that we aren’t going OOB at runtime
Expansion
#define __bit_index_ok(n, bits) \
((__UINTMAX_TYPE__) (__INTMAX_TYPE__) (n) < (__UINTMAX_TYPE__) (bits)) _BIT_CAPTURE
Section titled “_BIT_CAPTURE”#define _BIT_CAPTURE(val, n) source Expansion
#define _BIT_CAPTURE(val, n) \
__auto_type __bit_v = (val); \
__auto_type __bit_n = (n); \
ct_typecheck_integer_as(__bit_v, val); \
ct_typecheck_integer_as(__bit_n, n); \
(void) enforce(__bit_index_ok(__bit_n, sizeof(__bit_v) * __CHAR_BIT__)) BIT_SET
Section titled “BIT_SET”#define BIT_SET(val, n) source Expansion
#define BIT_SET(val, n) \
({ \
_BIT_CAPTURE(val, n); \
(typeof(__bit_v)) ((uint64_t) __bit_v | (UINT64_C(1) << __bit_n)); \
}) BIT_CLEAR
Section titled “BIT_CLEAR”#define BIT_CLEAR(val, n) source Expansion
#define BIT_CLEAR(val, n) \
({ \
_BIT_CAPTURE(val, n); \
(typeof(__bit_v)) ((uint64_t) __bit_v & ~(UINT64_C(1) << __bit_n)); \
}) BIT_TOGGLE
Section titled “BIT_TOGGLE”#define BIT_TOGGLE(val, n) source Expansion
#define BIT_TOGGLE(val, n) \
({ \
_BIT_CAPTURE(val, n); \
(typeof(__bit_v)) ((uint64_t) __bit_v ^ (UINT64_C(1) << __bit_n)); \
}) BIT_TEST
Section titled “BIT_TEST”#define BIT_TEST(val, n) source Expansion
#define BIT_TEST(val, n) \
({ \
_BIT_CAPTURE(val, n); \
(bool) (((uint64_t) __bit_v >> __bit_n) & UINT64_C(1)); \
}) BIT_MASK
Section titled “BIT_MASK”#define BIT_MASK(lo, hi) source Inclusive bit range as a uint64_t mask, with lo and hi evaluated and checked
Expansion
#define BIT_MASK(lo, hi) \
({ \
__auto_type __msk_lo = (lo); \
__auto_type __msk_hi = (hi); \
ct_typecheck_integer_as(__msk_lo, lo); \
ct_typecheck_integer_as(__msk_hi, hi); \
(void) enforce(__bit_index_ok(__msk_hi, 64) && \
(__UINTMAX_TYPE__) (__INTMAX_TYPE__) __msk_lo <= \
(__UINTMAX_TYPE__) (__INTMAX_TYPE__) __msk_hi); \
uint32_t __msk_l = (uint32_t) __msk_lo; \
uint32_t __msk_h = (uint32_t) __msk_hi; \
(~UINT64_C(0) >> (63u - (__msk_h - __msk_l))) << __msk_l; \
}) BIT_GET_FIELD
Section titled “BIT_GET_FIELD”#define BIT_GET_FIELD(val, lo, hi) source Expansion
#define BIT_GET_FIELD(val, lo, hi) \
({ \
__auto_type __fld_v = (val); \
uint32_t __fld_l = (uint32_t) (lo); \
uint32_t __fld_h = (uint32_t) (hi); \
ct_typecheck_integer_as(__fld_v, val); \
(void) enforce(__fld_l <= __fld_h && \
__fld_h < (sizeof(__fld_v) * __CHAR_BIT__)); \
(typeof(__fld_v)) (((uint64_t) __fld_v >> __fld_l) & \
(~UINT64_C(0) >> (63u - (__fld_h - __fld_l)))); \
}) BIT_SET_FIELD
Section titled “BIT_SET_FIELD”#define BIT_SET_FIELD(val, field_val, lo, hi) source Expansion
#define BIT_SET_FIELD(val, field_val, lo, hi) \
({ \
__auto_type __fld_v = (val); \
uint64_t __fld_fv = (uint64_t) (field_val); \
uint32_t __fld_l = (uint32_t) (lo); \
uint32_t __fld_h = (uint32_t) (hi); \
ct_typecheck_integer_as(__fld_v, val); \
(void) enforce(__fld_l <= __fld_h && \
__fld_h < (sizeof(__fld_v) * __CHAR_BIT__)); \
uint64_t __fld_mask = (~UINT64_C(0) >> (63u - (__fld_h - __fld_l))) \
<< __fld_l; \
(typeof(__fld_v)) (((uint64_t) __fld_v & ~__fld_mask) | \
((__fld_fv << __fld_l) & __fld_mask)); \
}) SET_FIELD
Section titled “SET_FIELD”#define SET_FIELD(val, field_val, lo, hi) source Expansion
#define SET_FIELD(val, field_val, lo, hi) BIT_SET_FIELD(val, field_val, lo, hi) BIT_RANGE
Section titled “BIT_RANGE”#define BIT_RANGE(val, lo, hi) source Expansion
#define BIT_RANGE(val, lo, hi) BIT_GET_FIELD(val, lo, hi) BIT_ANY
Section titled “BIT_ANY”#define BIT_ANY(val, mask) source Expansion
#define BIT_ANY(val, mask) \
({ \
__auto_type __any_v = (val); \
__auto_type __any_m = (mask); \
typedef ct_common_type_2(__any_v, __any_m) __any_t; \
ct_typecheck_widenable_to((__any_t) 0, val); \
ct_typecheck_widenable_to((__any_t) 0, mask); \
(bool) (((__any_t) __any_v & (__any_t) __any_m) != 0); \
}) BIT_ALL
Section titled “BIT_ALL”#define BIT_ALL(val, mask) source Expansion
#define BIT_ALL(val, mask) \
({ \
__auto_type __all_v = (val); \
__auto_type __all_m = (mask); \
typedef ct_common_type_2(__all_v, __all_m) __all_t; \
ct_typecheck_widenable_to((__all_t) 0, val); \
ct_typecheck_widenable_to((__all_t) 0, mask); \
(bool) (((__all_t) __all_v & (__all_t) __all_m) == (__all_t) __all_m); \
})