Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitswap function using template metaprogramming

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;
}
  • Is there any way to speed up this function by using template metaprogramming recursion to unroll the loop?
  • Is there a way to make it work with extended types such as __uint128_t? (the original version works with __uint128_t)
  • Does this function work theoretically to reverse the bits of types with a non-power of two number of bits if digits is correctly initialized to the correct number of bits? (for example a hypotherical uint41_t).
like image 731
Vincent Avatar asked Nov 09 '22 09:11

Vincent


1 Answers

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);
}
like image 83
lorro Avatar answered Nov 14 '22 23:11

lorro