Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef BITMATH_FUNC_HPP
00013 #define BITMATH_FUNC_HPP
00014
00033 template <typename T>
00034 static inline uint GB(const T x, const uint8 s, const uint8 n)
00035 {
00036 return (x >> s) & (((T)1U << n) - 1);
00037 }
00038
00059 template <typename T, typename U>
00060 static inline T SB(T &x, const uint8 s, const uint8 n, const U d)
00061 {
00062 x &= (T)(~((((T)1U << n) - 1) << s));
00063 x |= (T)(d << s);
00064 return x;
00065 }
00066
00084 template <typename T, typename U>
00085 static inline T AB(T &x, const uint8 s, const uint8 n, const U i)
00086 {
00087 const T mask = ((((T)1U << n) - 1) << s);
00088 x = (T)((x & ~mask) | ((x + (i << s)) & mask));
00089 return x;
00090 }
00091
00104 template <typename T>
00105 static inline bool HasBit(const T x, const uint8 y)
00106 {
00107 return (x & ((T)1U << y)) != 0;
00108 }
00109
00122 template <typename T>
00123 static inline T SetBit(T &x, const uint8 y)
00124 {
00125 return x = (T)(x | ((T)1U << y));
00126 }
00127
00138 #define SETBITS(x, y) ((x) |= (y))
00139
00152 template <typename T>
00153 static inline T ClrBit(T &x, const uint8 y)
00154 {
00155 return x = (T)(x & ~((T)1U << y));
00156 }
00157
00168 #define CLRBITS(x, y) ((x) &= ~(y))
00169
00182 template <typename T>
00183 static inline T ToggleBit(T &x, const uint8 y)
00184 {
00185 return x = (T)(x ^ ((T)1U << y));
00186 }
00187
00188
00190 extern const uint8 _ffb_64[64];
00191
00202 #define FIND_FIRST_BIT(x) _ffb_64[(x)]
00203
00218 static inline uint8 FindFirstBit2x64(const int value)
00219 {
00220 if ((value & 0xFF) == 0) {
00221 return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8;
00222 } else {
00223 return FIND_FIRST_BIT(value & 0x3F);
00224 }
00225 }
00226
00227 uint8 FindFirstBit(uint32 x);
00228 uint8 FindLastBit(uint64 x);
00229
00240 template <typename T>
00241 static inline T KillFirstBit(T value)
00242 {
00243 return value &= (T)(value - 1);
00244 }
00245
00252 template <typename T>
00253 static inline uint CountBits(T value)
00254 {
00255 uint num;
00256
00257
00258
00259
00260
00261
00262 for (num = 0; value != 0; num++) {
00263 value &= (T)(value - 1);
00264 }
00265
00266 return num;
00267 }
00268
00275 template <typename T>
00276 static inline bool HasExactlyOneBit(T value)
00277 {
00278 return value != 0 && (value & (value - 1)) == 0;
00279 }
00280
00287 template <typename T>
00288 static inline bool HasAtMostOneBit(T value)
00289 {
00290 return (value & (value - 1)) == 0;
00291 }
00292
00302 template <typename T>
00303 static inline T ROL(const T x, const uint8 n)
00304 {
00305 return (T)(x << n | x >> (sizeof(x) * 8 - n));
00306 }
00307
00317 template <typename T>
00318 static inline T ROR(const T x, const uint8 n)
00319 {
00320 return (T)(x >> n | x << (sizeof(x) * 8 - n));
00321 }
00322
00340 #define FOR_EACH_SET_BIT_EX(Tbitpos_type, bitpos_var, Tbitset_type, bitset_value) \
00341 for ( \
00342 Tbitset_type ___FESBE_bits = (bitpos_var = (Tbitpos_type)0, bitset_value); \
00343 ___FESBE_bits != (Tbitset_type)0; \
00344 ___FESBE_bits = (Tbitset_type)(___FESBE_bits >> 1), bitpos_var++ \
00345 ) \
00346 if ((___FESBE_bits & 1) != 0)
00347
00361 #define FOR_EACH_SET_BIT(bitpos_var, bitset_value) FOR_EACH_SET_BIT_EX(uint, bitpos_var, uint, bitset_value)
00362
00363 #if defined(__APPLE__)
00364
00365
00366
00367
00368 #define BSWAP32(x) ((uint32)Endian32_Swap(x))
00369 #define BSWAP16(x) ((uint16)Endian16_Swap(x))
00370 #elif defined(_MSC_VER)
00371
00372 #define BSWAP32(x) (_byteswap_ulong(x))
00373 #define BSWAP16(x) (_byteswap_ushort(x))
00374 #else
00375
00380 static inline uint32 BSWAP32(uint32 x)
00381 {
00382 #if !defined(__ICC) && defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ >= 3))
00383
00384 return (uint32)__builtin_bswap32((int32)x);
00385 #else
00386 return ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000) | ((x << 24) & 0xFF000000);
00387 #endif
00388 }
00389
00395 static inline uint16 BSWAP16(uint16 x)
00396 {
00397 return (x >> 8) | (x << 8);
00398 }
00399 #endif
00400
00401 #endif