The bit twiddling hacks website propose the following very efficient function to reverse bits:
// Bitswap: reverse the bits of the value of unsigned integral type T
template <class T>
constexpr T bitswap(T src)
{
    constexpr std::size_t char_bit = std::numeric_limits<unsigned char>::digits;
    constexpr std::size_t digits = sizeof(T) * char_bit;
    std::size_t size = digits;
    T mask = ~T();        
    while ((size >>= 1) > 0) {
        mask ^= (mask << size);
        src = ((src >> size) & mask) | ((src << size) & ~mask);
    }
    return src;
}
__uint128_t? (the original version works with __uint128_t)digits is correctly initialized to the correct number of bits? (for example a hypotherical uint41_t).You can't enforce rolling out templated calls, but chances are, this will end up in one single inlined function in an optimized build:
#include <iostream>
#include <limits>
#include <iomanip>
template <class T, int size = ((std::numeric_limits<unsigned char>::digits
                                * sizeof(T)) >> 1)>
struct Swap
{
    static constexpr T bitswap(T src, T mask = ~T())
    {
        mask ^= (mask << size);
        src = ((src >> size) & mask) | ((src << size) & ~mask);
        return Swap<T, (size >> 1)>::bitswap(src, mask);
    }
};
template <class T>
struct Swap<T, 0>
{
    static constexpr T bitswap(T src, T mask)
    {
        return src;
    }
};
template <class T>
constexpr T bitswap(T src)
{
    return Swap<T>::bitswap(src);
}
int main() {
    std::cout << std::hex << bitswap(0x12345678l);
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With