OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

bitmath_func.hpp
Go to the documentation of this file.
1 /* $Id: bitmath_func.hpp 25685 2013-08-05 20:37:29Z michi_cc $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
9
12 #ifndef BITMATH_FUNC_HPP
13 #define BITMATH_FUNC_HPP
14
33 template <typename T>
34 static inline uint GB(const T x, const uint8 s, const uint8 n)
35 {
36 return (x >> s) & (((T)1U << n) - 1);
37 }
38
59 template <typename T, typename U>
60 static inline T SB(T &x, const uint8 s, const uint8 n, const U d)
61 {
62 x &= (T)(~((((T)1U << n) - 1) << s));
63 x |= (T)(d << s);
64 return x;
65 }
66
84 template <typename T, typename U>
85 static inline T AB(T &x, const uint8 s, const uint8 n, const U i)
86 {
87 const T mask = ((((T)1U << n) - 1) << s);
88 x = (T)((x & ~mask) | ((x + (i << s)) & mask));
89 return x;
90 }
91
104 template <typename T>
105 static inline bool HasBit(const T x, const uint8 y)
106 {
107 return (x & ((T)1U << y)) != 0;
108 }
109
122 template <typename T>
123 static inline T SetBit(T &x, const uint8 y)
124 {
125 return x = (T)(x | ((T)1U << y));
126 }
127
138 #define SETBITS(x, y) ((x) |= (y))
139
152 template <typename T>
153 static inline T ClrBit(T &x, const uint8 y)
154 {
155 return x = (T)(x & ~((T)1U << y));
156 }
157
168 #define CLRBITS(x, y) ((x) &= ~(y))
169
182 template <typename T>
183 static inline T ToggleBit(T &x, const uint8 y)
184 {
185 return x = (T)(x ^ ((T)1U << y));
186 }
187
188
190 extern const uint8 _ffb_64[64];
191
202 #define FIND_FIRST_BIT(x) _ffb_64[(x)]
203
218 static inline uint8 FindFirstBit2x64(const int value)
219 {
220 if ((value & 0xFF) == 0) {
221 return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8;
222 } else {
223 return FIND_FIRST_BIT(value & 0x3F);
224 }
225 }
226
227 uint8 FindFirstBit(uint32 x);
228 uint8 FindLastBit(uint64 x);
229
240 template <typename T>
241 static inline T KillFirstBit(T value)
242 {
243 return value &= (T)(value - 1);
244 }
245
252 template <typename T>
253 static inline uint CountBits(T value)
254 {
255 uint num;
256
257 /* This loop is only called once for every bit set by clearing the lowest
258 * bit in each loop. The number of bits is therefore equal to the number of
259 * times the loop was called. It was found at the following website:
260 * http://graphics.stanford.edu/~seander/bithacks.html */
261
262 for (num = 0; value != 0; num++) {
263 value &= (T)(value - 1);
264 }
265
266 return num;
267 }
268
275 template <typename T>
276 static inline bool HasExactlyOneBit(T value)
277 {
278 return value != 0 && (value & (value - 1)) == 0;
279 }
280
287 template <typename T>
288 static inline bool HasAtMostOneBit(T value)
289 {
290 return (value & (value - 1)) == 0;
291 }
292
302 template <typename T>
303 static inline T ROL(const T x, const uint8 n)
304 {
305 return (T)(x << n | x >> (sizeof(x) * 8 - n));
306 }
307
317 template <typename T>
318 static inline T ROR(const T x, const uint8 n)
319 {
320 return (T)(x >> n | x << (sizeof(x) * 8 - n));
321 }
322
340 #define FOR_EACH_SET_BIT_EX(Tbitpos_type, bitpos_var, Tbitset_type, bitset_value) \
341 for ( \
342 Tbitset_type ___FESBE_bits = (bitpos_var = (Tbitpos_type)0, bitset_value); \
343 ___FESBE_bits != (Tbitset_type)0; \
344 ___FESBE_bits = (Tbitset_type)(___FESBE_bits >> 1), bitpos_var++ \
345 ) \
346 if ((___FESBE_bits & 1) != 0)
347
361 #define FOR_EACH_SET_BIT(bitpos_var, bitset_value) FOR_EACH_SET_BIT_EX(uint, bitpos_var, uint, bitset_value)
362
363 #if defined(__APPLE__)
364 /* Make endian swapping use Apple's macros to increase speed
365 * (since it will use hardware swapping if available).
366 * Even though they should return uint16 and uint32, we get
367 * warnings if we don't cast those (why?) */
368 #define BSWAP32(x) ((uint32)CFSwapInt32(x))
369 #define BSWAP16(x) ((uint16)CFSwapInt16(x))
370 #elif defined(_MSC_VER)
371 /* MSVC has intrinsics for swapping, resulting in faster code */
372 #define BSWAP32(x) (_byteswap_ulong(x))
373 #define BSWAP16(x) (_byteswap_ushort(x))
374 #else
375
380 static inline uint32 BSWAP32(uint32 x)
381 {
382 #if !defined(__ICC) && defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ >= 3))
383 /* GCC >= 4.3 provides a builtin, resulting in faster code */
384 return (uint32)__builtin_bswap32((int32)x);
385 #else
386 return ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000) | ((x << 24) & 0xFF000000);
387 #endif /* defined(__GNUC__) */
388 }
389
395 static inline uint16 BSWAP16(uint16 x)
396 {
397 return (x >> 8) | (x << 8);
398 }
399 #endif /* __APPLE__ */
400
401 #endif /* BITMATH_FUNC_HPP */