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 */

Generated on Sun Jan 23 01:49:01 2011 for OpenTTD by  doxygen 1.6.1