bit_util: Use Ones to implement Bits

This commit is contained in:
MerryMage 2018-06-27 14:37:52 +01:00
parent 62b640b2fa
commit 95ad0d0a66

View file

@ -21,15 +21,23 @@ constexpr size_t BitSize() {
return sizeof(T) * CHAR_BIT; return sizeof(T) * CHAR_BIT;
} }
template <typename T>
inline T Ones(size_t count) {
ASSERT_MSG(count <= BitSize<T>(), "count larger than bitsize of T");
if (count == BitSize<T>())
return static_cast<T>(~static_cast<T>(0));
return ~(static_cast<T>(~static_cast<T>(0)) << count);
}
/// Extract bits [begin_bit, end_bit] inclusive from value of type T. /// Extract bits [begin_bit, end_bit] inclusive from value of type T.
template<size_t begin_bit, size_t end_bit, typename T> template<size_t begin_bit, size_t end_bit, typename T>
constexpr T Bits(const T value) { constexpr T Bits(const T value) {
static_assert(begin_bit <= end_bit, static_assert(begin_bit <= end_bit,
"invalid bit range (position of beginning bit cannot be greater than that of end bit)"); "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
static_assert(begin_bit < BitSize<T>(), "begin_bit must be smaller than size of T"); static_assert(begin_bit < BitSize<T>(), "begin_bit must be smaller than size of T");
static_assert(end_bit < BitSize<T>(), "begin_bit must be smaller than size of T"); static_assert(end_bit < BitSize<T>(), "end_bit must be smaller than size of T");
return (value >> begin_bit) & ((1 << (end_bit - begin_bit + 1)) - 1); return (value >> begin_bit) & Ones<T>(end_bit - begin_bit + 1);
} }
#ifdef _MSC_VER #ifdef _MSC_VER
@ -143,14 +151,6 @@ inline size_t LowestSetBit(T value) {
return result; return result;
} }
template <typename T>
inline T Ones(size_t count) {
ASSERT_MSG(count <= BitSize<T>(), "count larger than bitsize of T");
if (count == BitSize<T>())
return ~static_cast<T>(0);
return ~(~static_cast<T>(0) << count);
}
template <typename T> template <typename T>
inline T Replicate(T value, size_t element_size) { inline T Replicate(T value, size_t element_size) {
ASSERT_MSG(BitSize<T>() % element_size == 0, "bitsize of T not divisible by element_size"); ASSERT_MSG(BitSize<T>() % element_size == 0, "bitsize of T not divisible by element_size");