# bitmath_func.hpp

Go to the documentation of this file.

    00001 /* $Id$ */
    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) & (((T)1U << n) - 1);
    00035 }
    00036
    00055 template <typename T, typename U>
    00056 static FORCEINLINE T SB(T &x, const uint8 s, const uint8 n, const U d)
    00057 {
    00058   x &= (T)(~((((T)1U << n) - 1) << s));
    00059   x |= (T)(d << s);
    00060   return x;
    00061 }
    00062
    00078 template <typename T, typename U>
    00079 static FORCEINLINE T AB(T &x, const uint8 s, const uint8 n, const U i)
    00080 {
    00081   const T mask = ((((T)1U << n) - 1) << s);
    00082   x = (T)((x & ~mask) | ((x + (i << s)) & mask));
    00083   return x;
    00084 }
    00085
    00097 template <typename T>
    00098 static FORCEINLINE bool HasBit(const T x, const uint8 y)
    00099 {
    00100   return (x & ((T)1U << y)) != 0;
    00101 }
    00102
    00114 template <typename T>
    00115 static FORCEINLINE T SetBit(T &x, const uint8 y)
    00116 {
    00117   return x = (T)(x | ((T)1U << y));
    00118 }
    00119
    00130 #define SETBITS(x, y) ((x) |= (y))
    00131
    00143 template <typename T>
    00144 static FORCEINLINE T ClrBit(T &x, const uint8 y)
    00145 {
    00146   return x = (T)(x & ~((T)1U << y));
    00147 }
    00148
    00159 #define CLRBITS(x, y) ((x) &= ~(y))
    00160
    00172 template <typename T>
    00173 static FORCEINLINE T ToggleBit(T &x, const uint8 y)
    00174 {
    00175   return x = (T)(x ^ ((T)1U << y));
    00176 }
    00177
    00178
    00180 extern const uint8 _ffb_64[64];
    00181
    00192 #define FIND_FIRST_BIT(x) _ffb_64[(x)]
    00193
    00208 static FORCEINLINE uint8 FindFirstBit2x64(const int value)
    00209 {
    00210   if ((value & 0xFF) == 0) {
    00211     return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8;
    00212   } else {
    00213     return FIND_FIRST_BIT(value & 0x3F);
    00214   }
    00215 }
    00216
    00217 uint8 FindFirstBit(uint32 x);
    00218 uint8 FindLastBit(uint64 x);
    00219
    00230 template <typename T>
    00231 static FORCEINLINE T KillFirstBit(T value)
    00232 {
    00233   return value &= (T)(value - 1);
    00234 }
    00235
    00242 template <typename T>
    00243 static inline uint CountBits(T value)
    00244 {
    00245   uint num;
    00246
    00247   /* This loop is only called once for every bit set by clearing the lowest
    00248    * bit in each loop. The number of bits is therefore equal to the number of
    00249    * times the loop was called. It was found at the following website:
    00250    * http://graphics.stanford.edu/~seander/bithacks.html */
    00251
    00252   for (num = 0; value != 0; num++) {
    00253     value &= (T)(value - 1);
    00254   }
    00255
    00256   return num;
    00257 }
    00258
    00265 template <typename T>
    00266 static FORCEINLINE bool HasExactlyOneBit(T value)
    00267 {
    00268   return value != 0 && (value & (value - 1)) == 0;
    00269 }
    00270
    00277 template <typename T>
    00278 static FORCEINLINE bool HasAtMostOneBit(T value)
    00279 {
    00280   return (value & (value - 1)) == 0;
    00281 }
    00282
    00291 template <typename T>
    00292 static FORCEINLINE T ROL(const T x, const uint8 n)
    00293 {
    00294   return (T)(x << n | x >> (sizeof(x) * 8 - n));
    00295 }
    00296
    00305 template <typename T>
    00306 static FORCEINLINE T ROR(const T x, const uint8 n)
    00307 {
    00308   return (T)(x >> n | x << (sizeof(x) * 8 - n));
    00309 }
    00310
    00328 #define FOR_EACH_SET_BIT_EX(Tbitpos_type, bitpos_var, Tbitset_type, bitset_value) \
    00329   for (                                                                           \
    00330     Tbitset_type ___FESBE_bits = (bitpos_var = (Tbitpos_type)0, bitset_value);    \
    00331     ___FESBE_bits != (Tbitset_type)0;                                             \
    00332     ___FESBE_bits = (Tbitset_type)(___FESBE_bits >> 1), bitpos_var++              \
    00333   )                                                                               \
    00334     if ((___FESBE_bits & 1) != 0)
    00335
    00349 #define FOR_EACH_SET_BIT(bitpos_var, bitset_value) FOR_EACH_SET_BIT_EX(uint, bitpos_var, uint, bitset_value)
    00350
    00351 #if defined(__APPLE__)
    00352   /* Make endian swapping use Apple's macros to increase speed
    00353    * (since it will use hardware swapping if available).
    00354    * Even though they should return uint16 and uint32, we get
    00355    * warnings if we don't cast those (why?) */
    00356   #define BSWAP32(x) ((uint32)Endian32_Swap(x))
    00357   #define BSWAP16(x) ((uint16)Endian16_Swap(x))
    00358 #else
    00359
    00364   static FORCEINLINE uint32 BSWAP32(uint32 x)
    00365   {
    00366 #if !defined(__ICC) && defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4)  && __GNUC_MINOR__ >= 3))
    00367     /* GCC >= 4.3 provides a builtin, resulting in faster code */
    00368     return (uint32)__builtin_bswap32((int32)x);
    00369 #else
    00370     return ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000) | ((x << 24) & 0xFF000000);
    00371 #endif /* defined(__GNUC__) */
    00372   }
    00373
    00379   static FORCEINLINE uint16 BSWAP16(uint16 x)
    00380   {
    00381     return (x >> 8) | (x << 8);
    00382   }
    00383 #endif /* __APPLE__ */
    00384
    00385 #endif /* BITMATH_FUNC_HPP */