/src/glaze/include/glaze/util/bit.hpp
Line | Count | Source |
1 | | // Glaze Library |
2 | | // For the license information refer to glaze.hpp |
3 | | |
4 | | #pragma once |
5 | | |
6 | | #include <bit> |
7 | | #include <cstdint> |
8 | | |
9 | | #include "glaze/util/inline.hpp" |
10 | | |
11 | | namespace glz |
12 | | { |
13 | | // std::countr_zero uses another branch check whether the input is zero, |
14 | | // we use this function when we know that x > 0 |
15 | | GLZ_ALWAYS_INLINE auto countr_zero(const uint32_t x) noexcept |
16 | 0 | { |
17 | 0 | #ifdef _MSC_VER |
18 | 0 | return std::countr_zero(x); |
19 | 0 | #else |
20 | 0 | #if __has_builtin(__builtin_ctzl) |
21 | 0 | return __builtin_ctzl(x); |
22 | 0 | #else |
23 | 0 | return std::countr_zero(x); |
24 | 0 | #endif |
25 | 0 | #endif |
26 | 0 | } |
27 | | |
28 | | GLZ_ALWAYS_INLINE auto countr_zero(const uint64_t x) noexcept |
29 | 0 | { |
30 | 0 | #ifdef _MSC_VER |
31 | 0 | return std::countr_zero(x); |
32 | 0 | #else |
33 | 0 | #if __has_builtin(__builtin_ctzll) |
34 | 0 | return __builtin_ctzll(x); |
35 | 0 | #else |
36 | 0 | return std::countr_zero(x); |
37 | 0 | #endif |
38 | 0 | #endif |
39 | 0 | } |
40 | | |
41 | | #if defined(__SIZEOF_INT128__) |
42 | | GLZ_ALWAYS_INLINE auto countr_zero(__uint128_t x) noexcept |
43 | 0 | { |
44 | 0 | uint64_t low = uint64_t(x); |
45 | 0 | if (low != 0) { |
46 | 0 | return countr_zero(low); |
47 | 0 | } |
48 | 0 | else { |
49 | 0 | uint64_t high = uint64_t(x >> 64); |
50 | 0 | return countr_zero(high) + 64; |
51 | 0 | } |
52 | 0 | } |
53 | | #endif |
54 | | |
55 | | // std::countl_zero uses another branch check whether the input is zero, |
56 | | // we use this function when we know that x > 0 |
57 | | GLZ_ALWAYS_INLINE constexpr auto countl_zero(const uint32_t x) noexcept |
58 | 0 | { |
59 | 0 | #ifdef _MSC_VER |
60 | 0 | return std::countl_zero(x); |
61 | 0 | #else |
62 | 0 | #if __has_builtin(__builtin_clz) |
63 | 0 | return __builtin_clz(x); |
64 | 0 | #else |
65 | 0 | return std::countl_zero(x); |
66 | 0 | #endif |
67 | 0 | #endif |
68 | 0 | } |
69 | | |
70 | 0 | constexpr int int_log2(uint32_t x) noexcept { return 31 - glz::countl_zero(x | 1); } |
71 | | } |