#include <stdio.h>
#include <time.h>
#define R2(n)     n,     n + 2*64,     n + 1*64,     n + 3*64
#define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16)
#define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 )
 
static const unsigned char BitReverseTable256[256] =
{
    R6(0), R6(2), R6(1), R6(3)
};
 
inline unsigned char ReverseBitsLookupTable(unsigned char v)
{
    return BitReverseTable256[v];
}
 
inline unsigned char ReverseBitsSimpleAndElegant(unsigned char ucByte)
{
    return (0x10 & ucByte) >> 1 | (0x08 & ucByte) << 1 |
           (0x20 & ucByte) >> 3 | (0x04 & ucByte) << 3 |
           (0x40 & ucByte) >> 5 | (0x02 & ucByte) << 5 |
           (0x80 & ucByte) >> 7 | (0x01 & ucByte) << 7;
}

inline unsigned char ReverseBits7ops32bit(unsigned char v)
{
    return ((v * 0x0802LU & 0x22110LU) | 
            (v * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
}

typedef unsigned char (*ReverseBitsFunc)(unsigned char);

unsigned int TestFunc(const char * desc, ReverseBitsFunc func)
{
    const unsigned int uiFunctionCallCount = 200000000;
    
    unsigned int res = 0;
    clock_t begin = clock();
    for(int i = 0; i < uiFunctionCallCount; ++i)
    {
         res += func((unsigned char)i);
    }
    
    clock_t end = clock();
    
    printf("%u calls of %s takes %lf seconds.\n", uiFunctionCallCount, desc,
        (double)(end - begin)/(double)CLOCKS_PER_SEC);
        
    return res;
}

int main()
{
    TestFunc("ReverseBitsSimpleAndElegant", ReverseBitsSimpleAndElegant);
    TestFunc("ReverseBitsLookupTable", ReverseBitsLookupTable);
    TestFunc("ReverseBits7ops32bit", ReverseBits7ops32bit);
    
    return 0;
}