# bitmath_func.hpp

Go to the documentation of this file.

    00001 /* $Id: bitmath_func.hpp 19019 2010-02-05 17:05:58Z smatz $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #ifndef BITMATH_FUNC_HPP
    00013 #define BITMATH_FUNC_HPP
    00014
    00031 template <typename T>
    00032 static FORCEINLINE uint GB(const T x, const uint8 s, const uint8 n)
    00033 {
    00034   return (x >> s) & ((1U << n) - 1);
    00035 }
    00036
    00054 template <typename T, typename U>
    00055 static FORCEINLINE T SB(T &x, const uint8 s, const uint8 n, const U d)
    00056 {
    00057   x &= (T)(~(((1U << n) - 1) << s));
    00058   x |= (T)(d << s);
    00059   return x;
    00060 }
    00061
    00076 template <typename T, typename U>
    00077 static FORCEINLINE T AB(T &x, const uint8 s, const uint8 n, const U i)
    00078 {
    00079   const T mask = (T)(((1U << n) - 1) << s);
    00080   x = (T)((x & ~mask) | ((x + (i << s)) & mask));
    00081   return x;
    00082 }
    00083
    00095 template <typename T>
    00096 static FORCEINLINE bool HasBit(const T x, const uint8 y)
    00097 {
    00098   return (x & ((T)1U << y)) != 0;
    00099 }
    00100
    00112 template <typename T>
    00113 static FORCEINLINE T SetBit(T &x, const uint8 y)
    00114 {
    00115   return x = (T)(x | (T)(1U << y));
    00116 }
    00117
    00128 #define SETBITS(x, y) ((x) |= (y))
    00129
    00141 template <typename T>
    00142 static FORCEINLINE T ClrBit(T &x, const uint8 y)
    00143 {
    00144   return x = (T)(x & ~((T)1U << y));
    00145 }
    00146
    00157 #define CLRBITS(x, y) ((x) &= ~(y))
    00158
    00170 template <typename T>
    00171 static FORCEINLINE T ToggleBit(T &x, const uint8 y)
    00172 {
    00173   return x = (T)(x ^ (T)(1U << y));
    00174 }
    00175
    00176
    00178 extern const uint8 _ffb_64[64];
    00179
    00190 #define FIND_FIRST_BIT(x) _ffb_64[(x)]
    00191
    00206 static FORCEINLINE uint8 FindFirstBit2x64(const int value)
    00207 {
    00208   if ((value & 0xFF) == 0) {
    00209     return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8;
    00210   } else {
    00211     return FIND_FIRST_BIT(value & 0x3F);
    00212   }
    00213 }
    00214
    00215 uint8 FindFirstBit(uint32 x);
    00216 uint8 FindLastBit(uint64 x);
    00217
    00228 template <typename T>
    00229 static FORCEINLINE T KillFirstBit(T value)
    00230 {
    00231   return value &= (T)(value - 1);
    00232 }
    00233
    00240 template <typename T>
    00241 static inline uint CountBits(T value)
    00242 {
    00243   uint num;
    00244
    00245   /* This loop is only called once for every bit set by clearing the lowest
    00246    * bit in each loop. The number of bits is therefore equal to the number of
    00247    * times the loop was called. It was found at the following website:
    00248    * http://graphics.stanford.edu/~seander/bithacks.html */
    00249
    00250   for (num = 0; value != 0; num++) {
    00251     value &= (T)(value - 1);
    00252   }
    00253
    00254   return num;
    00255 }
    00256
    00263 template <typename T>
    00264 static FORCEINLINE bool HasExactlyOneBit(T value)
    00265 {
    00266   return value != 0 && (value & (value - 1)) == 0;
    00267 }
    00268
    00275 template <typename T>
    00276 static FORCEINLINE bool HasAtMostOneBit(T value)
    00277 {
    00278   return (value & (value - 1)) == 0;
    00279 }
    00280
    00289 template <typename T>
    00290 static FORCEINLINE T ROL(const T x, const uint8 n)
    00291 {
    00292   return (T)(x << n | x >> (sizeof(x) * 8 - n));
    00293 }
    00294
    00303 template <typename T>
    00304 static FORCEINLINE T ROR(const T x, const uint8 n)
    00305 {
    00306   return (T)(x >> n | x << (sizeof(x) * 8 - n));
    00307 }
    00308
    00320 #define FOR_EACH_SET_BIT(i, b)      \
    00321   for (i = 0; b != 0; i++, b >>= 1) \
    00322     if (b & 1)
    00323
    00324
    00325 #if defined(__APPLE__)
    00326   /* Make endian swapping use Apple's macros to increase speed
    00327    * (since it will use hardware swapping if available).
    00328    * Even though they should return uint16 and uint32, we get
    00329    * warnings if we don't cast those (why?) */
    00330   #define BSWAP32(x) ((uint32)Endian32_Swap(x))
    00331   #define BSWAP16(x) ((uint16)Endian16_Swap(x))
    00332 #else
    00333
    00338   static FORCEINLINE uint32 BSWAP32(uint32 x)
    00339   {
    00340 #if !defined(__ICC) && defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4)  && __GNUC_MINOR__ >= 3))
    00341     /* GCC >= 4.3 provides a builtin, resulting in faster code */
    00342     return (uint32)__builtin_bswap32((int32)x);
    00343 #else
    00344     return ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000) | ((x << 24) & 0xFF000000);
    00345 #endif /* defined(__GNUC__) */
    00346   }
    00347
    00353   static FORCEINLINE uint16 BSWAP16(uint16 x)
    00354   {
    00355     return (x >> 8) | (x << 8);
    00356   }
    00357 #endif /* __APPLE__ */
    00358
    00359 #endif /* BITMATH_FUNC_HPP */