1 /**************************************************************************** 2 * Copyright (C) 2014 by Jens Nissen jens-chessx@gmx.net * 3 ****************************************************************************/ 4 5 #include <qglobal.h> 6 7 #ifndef BITFIND_H 8 #define BITFIND_H 9 10 template <typename T> getFirstBitAndClear64(quint64 & bb)11T getFirstBitAndClear64(quint64& bb) 12 { 13 quint64 x = bb & -(qint64)bb; 14 bb ^= x; 15 #ifdef __GNUG__ 16 return T(x ? (63 - __builtin_clzll(x)) : (T)0xFF); 17 #elif _MSC_VER 18 #ifdef __x86_64__ 19 if(x) 20 { 21 unsigned long r; 22 _BitScanReverse64(&r, x); 23 return T(r); 24 } 25 return (T)0xFF; 26 #else 27 if(x) 28 { 29 unsigned long r; 30 unsigned long y = (x >> 32); 31 if(y) 32 { 33 _BitScanReverse(&r, y); 34 return T(32 + r); 35 } 36 _BitScanReverse(&r, x); 37 return T(r); 38 } 39 return (T)0xFF; 40 #endif 41 #else 42 // SBE - After a fair bit of testing, this is the fastest portable version 43 // i could come up with, it's about twice as fast as shift-testing 64 times. 44 unsigned int r = 0; 45 if (!x) return 0xFF; 46 if(!(x & 0xffffffff)) 47 { 48 x >>= 32; 49 r |= 32; 50 } 51 if(!(x & 0xffff)) 52 { 53 x >>= 16; 54 r |= 16; 55 } 56 if(!(x & 0xff)) 57 { 58 x >>= 8; 59 r |= 8; 60 } 61 if(!(x & 0xf)) 62 { 63 x >>= 4; 64 r |= 4; 65 } 66 if(!(x & 0x3)) 67 { 68 x >>= 2; 69 r |= 2; 70 } 71 if(!(x & 0x1)) 72 { 73 r |= 1; 74 } 75 return T(r); 76 #endif 77 } 78 79 #endif // BITFIND_H 80