| #ifndef strings_h |
| #define strings_h |
| |
| /* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided |
| * for both */ |
| #ifdef _MSC_VER |
| # include <intrin.h> |
| # pragma intrinsic(_BitScanForward) |
| static __forceinline int ffsl(long x) { |
| unsigned long i; |
| |
| if (_BitScanForward(&i, x)) { |
| return i + 1; |
| } |
| return 0; |
| } |
| |
| static __forceinline int ffs(int x) { |
| return ffsl(x); |
| } |
| |
| # ifdef _M_X64 |
| # pragma intrinsic(_BitScanForward64) |
| # endif |
| |
| static __forceinline int ffsll(unsigned __int64 x) { |
| unsigned long i; |
| #ifdef _M_X64 |
| if (_BitScanForward64(&i, x)) { |
| return i + 1; |
| } |
| return 0; |
| #else |
| // Fallback for 32-bit build where 64-bit version not available |
| // assuming little endian |
| union { |
| unsigned __int64 ll; |
| unsigned long l[2]; |
| } s; |
| |
| s.ll = x; |
| |
| if (_BitScanForward(&i, s.l[0])) { |
| return i + 1; |
| } else if(_BitScanForward(&i, s.l[1])) { |
| return i + 33; |
| } |
| return 0; |
| #endif |
| } |
| |
| #else |
| # define ffsll(x) __builtin_ffsll(x) |
| # define ffsl(x) __builtin_ffsl(x) |
| # define ffs(x) __builtin_ffs(x) |
| #endif |
| |
| #endif /* strings_h */ |