diff --git a/src/common/bit_util.h b/src/common/bit_util.h index 25ed3fc3..2a515533 100644 --- a/src/common/bit_util.h +++ b/src/common/bit_util.h @@ -40,6 +40,29 @@ constexpr T Bits(const T value) { return (value >> begin_bit) & Ones(end_bit - begin_bit + 1); } +/// Create a mask of type T for bits [begin_bit, end_bit] inclusive. +template +constexpr T Mask() { + static_assert(begin_bit <= end_bit, + "invalid bit range (position of beginning bit cannot be greater than that of end bit)"); + static_assert(begin_bit < BitSize(), "begin_bit must be smaller than size of T"); + static_assert(end_bit < BitSize(), "end_bit must be smaller than size of T"); + + return Ones(end_bit - begin_bit + 1) << begin_bit; +} + +/// Clears bits [begin_bit, end_bit] inclusive of value of type T. +template +constexpr T ClearBits(const T value) { + return value & ~Mask(); +} + +/// Modifies bits [begin_bit, end_bit] inclusive of value of type T. +template +constexpr T ModifyBits(const T value, const T new_bits) { + return ClearBits(value) | ((new_bits << begin_bit) & Mask()); +} + #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4554)