# bitmath_func.hpp

Go to the documentation of this file.

    00001 /* $Id: bitmath_func.hpp 24959 2013-02-02 20:18:41Z rubidium $ */
    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
    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   /* This loop is only called once for every bit set by clearing the lowest
    00258    * bit in each loop. The number of bits is therefore equal to the number of
    00259    * times the loop was called. It was found at the following website:
    00260    * http://graphics.stanford.edu/~seander/bithacks.html */
    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   /* Make endian swapping use Apple's macros to increase speed
    00365    * (since it will use hardware swapping if available).
    00366    * Even though they should return uint16 and uint32, we get
    00367    * warnings if we don't cast those (why?) */
    00368   #define BSWAP32(x) ((uint32)Endian32_Swap(x))
    00369   #define BSWAP16(x) ((uint16)Endian16_Swap(x))
    00370 #elif defined(_MSC_VER)
    00371   /* MSVC has intrinsics for swapping, resulting in faster code */
    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     /* GCC >= 4.3 provides a builtin, resulting in faster code */
    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 /* defined(__GNUC__) */
    00388   }
    00389
    00395   static inline uint16 BSWAP16(uint16 x)
    00396   {
    00397     return (x >> 8) | (x << 8);
    00398   }
    00399 #endif /* __APPLE__ */
    00400
    00401 #endif /* BITMATH_FUNC_HPP */