24 #ifndef TSL_ROBIN_GROWTH_POLICY_H
25 #define TSL_ROBIN_GROWTH_POLICY_H
38 #define tsl_rh_assert(expr) assert(expr)
40 #define tsl_rh_assert(expr) (static_cast<void>(0))
47 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || \
48 (defined(_MSC_VER) && defined(_CPPUNWIND))) && \
49 !defined(TSL_NO_EXCEPTIONS)
50 #define TSL_RH_THROW_OR_TERMINATE(ex, msg) throw ex(msg)
52 #define TSL_RH_NO_EXCEPTIONS
54 #define TSL_RH_THROW_OR_TERMINATE(ex, msg) std::terminate()
57 #define TSL_RH_THROW_OR_TERMINATE(ex, msg) \
59 std::cerr << msg << std::endl; \
65 #if defined(__GNUC__) || defined(__clang__)
66 #define TSL_RH_LIKELY(exp) (__builtin_expect(!!(exp), true))
68 #define TSL_RH_LIKELY(exp) (exp)
98 if (min_bucket_count_in_out > 0) {
100 m_mask = min_bucket_count_in_out - 1;
122 return (
m_mask + 1) * GrowthFactor;
131 return (std::numeric_limits<std::size_t>::max() / 2) + 1;
152 for (std::size_t i = 1; i <
sizeof(std::size_t) * CHAR_BIT; i *= 2) {
161 return value != 0 && (value & (value - 1)) == 0;
166 "GrowthFactor must be a power of two >= 2.");
184 if (min_bucket_count_in_out > 0) {
185 m_mod = min_bucket_count_in_out;
200 const double nxt_bucket_count =
202 if (!std::isnormal(nxt_bucket_count)) {
210 return std::size_t(nxt_bucket_count);
220 1.0 * GrowthFactor::num / GrowthFactor::den;
231 static constexpr
const std::array<std::size_t, 40>
PRIMES = {
232 {1ul, 5ul, 17ul, 29ul, 37ul, 53ul,
233 67ul, 79ul, 97ul, 131ul, 193ul, 257ul,
234 389ul, 521ul, 769ul, 1031ul, 1543ul, 2053ul,
235 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul,
236 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, 6291469ul,
237 12582917ul, 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul,
238 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul}};
240 template <
unsigned int IPrime>
static constexpr std::size_t
mod(std::size_t hash)
242 return hash %
PRIMES[IPrime];
248 static constexpr
const std::array<std::size_t (*)(std::size_t), 40>
MOD_PRIME = {
249 {&mod<0>, &mod<1>, &mod<2>, &mod<3>, &mod<4>, &mod<5>, &mod<6>, &mod<7>,
250 &mod<8>, &mod<9>, &mod<10>, &mod<11>, &mod<12>, &mod<13>, &mod<14>, &mod<15>,
251 &mod<16>, &mod<17>, &mod<18>, &mod<19>, &mod<20>, &mod<21>, &mod<22>, &mod<23>,
252 &mod<24>, &mod<25>, &mod<26>, &mod<27>, &mod<28>, &mod<29>, &mod<30>, &mod<31>,
253 &mod<32>, &mod<33>, &mod<34>, &mod<35>, &mod<36>, &mod<37>, &mod<38>, &mod<39>}};
296 if (min_bucket_count_in_out > 0) {
297 min_bucket_count_in_out = *it_prime;
300 min_bucket_count_in_out = 0;
326 "The type of m_iprime is not big enough.");