I'm trying to toggle the most significant bit of an unsigned int
based on a bool
flag. This is my code for an hypothetical K = unit64_t
:
This is the Item
class:
template<typename K>
class Item {
public:
K first;
Item() = default;
explicit Item(const K &elem, const bool flag = false) {
first = elem & 0x3FFFFFFFFFFFFFFF;
first |= (flag * 0x8000000000000000);
}
};
Is there a way to do this fully generical? That it works for all kind of numeric K
?
I tried with the 8 * sizeof(K)
but it doesn't work.
CodePudding user response:
You can leverage std::bitset
for this. Not sure how well this optimizes, but it should optimize well and it will work generically and requires no bitwise operation knowledge.
template <typename T>
void toggle_msb(T& val)
{
constexpr auto bit_width = sizeof(T) * CHAR_BIT;
std::bitset<bit_width> temp(val);
val = temp.flip(bit_width - 1).to_ullong();
}
CodePudding user response:
An option using only bit operations:
template<typename T>
void Item(T& elem, bool flag = false) {
T mask = (T)1 << (sizeof(T) * 8 - 1);
elem = (elem & ~mask) | (flag ? mask : 0);
}
CodePudding user response:
Using bitwise operations, but without explicitly depending on the size of T
:
template<typename T>
T set_top_bit(T value, bool state) {
constexpr T mask = T(~T(0)) >> 1;
value &= mask;
if (state) value |= ~mask;
return value;
}
T(~T(0))
gets a T
with all bits set1; >> 1
throws out the bottom bit getting a 0 in from the top, so in mask
we have a T
with all bit set but the topmost. Notice that all this dance is purely formal—this is all evaluated at compile time.
The rest is pretty much like your code: mask out the top bit from value
and OR it back in depending on state
(~mask
will be a T
with only the top bit set).
- Plain
~0
would result in anint
set to -1,~0U
in anunsigned int
with all bits set; to obtain aT
with all bits set, we need to flip the bits of aT(0)
(so, a 0 of our T type), and also to cast back toT
later, because, ifT
is smaller thanint
,~T(0)
is actually equivalent to~int(T(0))
, so~0
, due to integer promotion rules.