10#include <rapidfuzz/details/config.hpp>
14#if defined(_MSC_VER) && !defined(__clang__)
22T bit_mask_lsb(
size_t n)
24 T mask =
static_cast<T
>(-1);
25 if (n <
sizeof(T) * 8) {
26 mask +=
static_cast<T
>(
static_cast<T
>(1) << n);
32bool bittest(T a,
int bit)
34 return (a >> bit) & 1;
41constexpr uint64_t shr64(uint64_t a, U shift)
43 return (shift < 64) ? a >> shift : 0;
50constexpr uint64_t shl64(uint64_t a, U shift)
52 return (shift < 64) ? a << shift : 0;
55RAPIDFUZZ_CONSTEXPR_CXX14 uint64_t addc64(uint64_t a, uint64_t b, uint64_t carryin, uint64_t* carryout)
59 *carryout = a < carryin;
65template <
typename T,
typename U>
66RAPIDFUZZ_CONSTEXPR_CXX14 T ceil_div(T a, U divisor)
68 T _div =
static_cast<T
>(divisor);
69 return a / _div +
static_cast<T
>(a % _div != 0);
72static inline size_t popcount(uint64_t x)
74 return std::bitset<64>(x).count();
77static inline size_t popcount(uint32_t x)
79 return std::bitset<32>(x).count();
82static inline size_t popcount(uint16_t x)
84 return std::bitset<16>(x).count();
87static inline size_t popcount(uint8_t x)
89 static constexpr uint8_t bit_count[256] = {
90 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
91 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
92 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
93 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
94 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
95 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
96 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
97 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
102RAPIDFUZZ_CONSTEXPR_CXX14 T rotl(T x,
unsigned int n)
104 unsigned int num_bits = std::numeric_limits<T>::digits;
105 assert(n < num_bits);
106 unsigned int count_mask = num_bits - 1;
108#if _MSC_VER && !defined(__clang__)
109# pragma warning(push)
111# pragma warning(disable : 4146)
113 return (x << n) | (x >> (-n & count_mask));
114#if _MSC_VER && !defined(__clang__)
125#if _MSC_VER && !defined(__clang__)
126# pragma warning(push)
128# pragma warning(disable : 4146)
131#if _MSC_VER && !defined(__clang__)
150constexpr T blsmsk(T a)
155#if defined(_MSC_VER) && !defined(__clang__)
156static inline unsigned int countr_zero(uint32_t x)
158 unsigned long trailing_zero = 0;
159 _BitScanForward(&trailing_zero, x);
160 return trailing_zero;
163# if defined(_M_ARM) || defined(_M_X64)
164static inline unsigned int countr_zero(uint64_t x)
166 unsigned long trailing_zero = 0;
167 _BitScanForward64(&trailing_zero, x);
168 return trailing_zero;
171static inline unsigned int countr_zero(uint64_t x)
173 uint32_t msh = (uint32_t)(x >> 32);
174 uint32_t lsh = (uint32_t)(x & 0xFFFFFFFF);
175 if (lsh != 0)
return countr_zero(lsh);
176 return 32 + countr_zero(msh);
181static inline unsigned int countr_zero(uint32_t x)
183 return static_cast<unsigned int>(__builtin_ctz(x));
186static inline unsigned int countr_zero(uint64_t x)
188 return static_cast<unsigned int>(__builtin_ctzll(x));
192static inline unsigned int countr_zero(uint16_t x)
194 return countr_zero(
static_cast<uint32_t
>(x));
197static inline unsigned int countr_zero(uint8_t x)
199 return countr_zero(
static_cast<uint32_t
>(x));
202template <
typename T, T N, T Pos = 0,
bool IsEmpty = (N == 0)>
205template <
typename T, T N, T Pos>
206struct UnrollImpl<T, N, Pos, false> {
207 template <
typename F>
208 static void call(F&& f)
211 UnrollImpl<T, N - 1, Pos + 1>::call(std::forward<F>(f));
215template <
typename T, T N, T Pos>
216struct UnrollImpl<T, N, Pos, true> {
217 template <
typename F>
218 static void call(F&&)
222template <
typename T, T N,
class F>
223RAPIDFUZZ_CONSTEXPR_CXX14
void unroll(F&& f)
225 UnrollImpl<T, N>::call(f);