# bitmath_func.hpp

Go to the documentation of this file.

    00001 /* $Id: bitmath_func.hpp 16310 2009-05-15 10:24:13Z rubidium $ */
    00002
    00005 #ifndef BITMATH_FUNC_HPP
    00006 #define BITMATH_FUNC_HPP
    00007
    00024 template <typename T>
    00025 static FORCEINLINE uint GB(const T x, const uint8 s, const uint8 n)
    00026 {
    00027   return (x >> s) & ((1U << n) - 1);
    00028 }
    00029
    00047 template <typename T, typename U>
    00048 static FORCEINLINE T SB(T &x, const uint8 s, const uint8 n, const U d)
    00049 {
    00050   x &= (T)(~(((1U << n) - 1) << s));
    00051   x |= (T)(d << s);
    00052   return x;
    00053 }
    00054
    00069 template <typename T, typename U>
    00070 static FORCEINLINE T AB(T &x, const uint8 s, const uint8 n, const U i)
    00071 {
    00072   const T mask = (T)(((1U << n) - 1) << s);
    00073   x = (T)((x & ~mask) | ((x + (i << s)) & mask));
    00074   return x;
    00075 }
    00076
    00088 template <typename T>
    00089 static FORCEINLINE bool HasBit(const T x, const uint8 y)
    00090 {
    00091   return (x & ((T)1U << y)) != 0;
    00092 }
    00093
    00104 #define HASBITS(x, y) (((x) & (y)) != 0)
    00105
    00117 template <typename T>
    00118 static FORCEINLINE T SetBit(T &x, const uint8 y)
    00119 {
    00120   return x = (T)(x | (T)(1U << y));
    00121 }
    00122
    00133 #define SETBITS(x, y) ((x) |= (y))
    00134
    00146 template <typename T>
    00147 static FORCEINLINE T ClrBit(T &x, const uint8 y)
    00148 {
    00149   return x = (T)(x & ~((T)1U << y));
    00150 }
    00151
    00162 #define CLRBITS(x, y) ((x) &= ~(y))
    00163
    00175 template <typename T>
    00176 static FORCEINLINE T ToggleBit(T &x, const uint8 y)
    00177 {
    00178   return x = (T)(x ^ (T)(1U << y));
    00179 }
    00180
    00181
    00183 extern const uint8 _ffb_64[64];
    00184
    00195 #define FIND_FIRST_BIT(x) _ffb_64[(x)]
    00196
    00211 static FORCEINLINE uint8 FindFirstBit2x64(const int value)
    00212 {
    00213   if ((value & 0xFF) == 0) {
    00214     return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8;
    00215   } else {
    00216     return FIND_FIRST_BIT(value & 0x3F);
    00217   }
    00218 }
    00219
    00220 uint8 FindFirstBit(uint32 x);
    00221 uint8 FindLastBit(uint64 x);
    00222
    00233 template <typename T>
    00234 static FORCEINLINE T KillFirstBit(T value)
    00235 {
    00236   return value &= (T)(value - 1);
    00237 }
    00238
    00245 template <typename T>
    00246 static inline uint CountBits(T value)
    00247 {
    00248   uint num;
    00249
    00250   /* This loop is only called once for every bit set by clearing the lowest
    00251    * bit in each loop. The number of bits is therefore equal to the number of
    00252    * times the loop was called. It was found at the following website:
    00253    * http://graphics.stanford.edu/~seander/bithacks.html */
    00254
    00255   for (num = 0; value != 0; num++) {
    00256     value &= (T)(value - 1);
    00257   }
    00258
    00259   return num;
    00260 }
    00261
    00270 template <typename T>
    00271 static FORCEINLINE T ROL(const T x, const uint8 n)
    00272 {
    00273   return (T)(x << n | x >> (sizeof(x) * 8 - n));
    00274 }
    00275
    00284 template <typename T>
    00285 static FORCEINLINE T ROR(const T x, const uint8 n)
    00286 {
    00287   return (T)(x >> n | x << (sizeof(x) * 8 - n));
    00288 }
    00289
    00301 #define FOR_EACH_SET_BIT(i, b)      \
    00302   for (i = 0; b != 0; i++, b >>= 1) \
    00303     if (b & 1)
    00304
    00305
    00306 #if defined(__APPLE__)
    00307   /* Make endian swapping use Apple's macros to increase speed
    00308    * (since it will use hardware swapping if available).
    00309    * Even though they should return uint16 and uint32, we get
    00310    * warnings if we don't cast those (why?) */
    00311   #define BSWAP32(x) ((uint32)Endian32_Swap(x))
    00312   #define BSWAP16(x) ((uint16)Endian16_Swap(x))
    00313 #else
    00314
    00319   static FORCEINLINE uint32 BSWAP32(uint32 x)
    00320   {
    00321 #if !defined(__ICC) && defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4)  && __GNUC_MINOR__ >= 3))
    00322     /* GCC >= 4.3 provides a builtin, resulting in faster code */
    00323     return (uint32)__builtin_bswap32((int32)x);
    00324 #else
    00325     return ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000) | ((x << 24) & 0xFF000000);
    00326 #endif /* defined(__GNUC__) */
    00327   }
    00328
    00334   static FORCEINLINE uint16 BSWAP16(uint16 x)
    00335   {
    00336     return (x >> 8) | (x << 8);
    00337   }
    00338 #endif /* __APPLE__ */
    00339
    00340 #endif /* BITMATH_FUNC_HPP */