26 template <
typename K,
typename V,
typename Hash = std::hash< K >,
typename KeyEqual = std::equal_to< K >,
typename Alloc = std::allocator< std::pair< const K, V > > >
29 enum class color : std::uint8_t
37 std::pair<const K, V> item;
43 using hash_type = std::uint64_t;
45 static constexpr std::size_t hash_per_bucket = std::max< std::size_t >(4, std::max< std::size_t >(std::hardware_destructive_interference_size, std::hardware_constructive_interference_size) /
sizeof(hash_type));
47 struct alignas(std::hardware_destructive_interference_size) bucket
49 std::array< hash_type, hash_per_bucket > bucket_hashes;
50 std::array< node*, hash_per_bucket > bucket_nodes;
57 static hash_type reverse_bits(hash_type i)
59 i = ((i & 0x5555555555555555) << 1) | ((i & 0xAAAAAAAAAAAAAAAA) >> 1);
60 i = ((i & 0x3333333333333333) << 2) | ((i & 0xCCCCCCCCCCCCCCCC) >> 2);
61 i = ((i & 0x0F0F0F0F0F0F0F0F) << 4) | ((i & 0xF0F0F0F0F0F0F0F0) >> 4);
62 i = ((i & 0x00FF00FF00FF00FF) << 8) | ((i & 0xFF00FF00FF00FF00) >> 8);
63 i = ((i & 0x0000FFFF0000FFFF) << 16) | ((i & 0xFFFF0000FFFF0000) >> 16);
64 i = (i << 32) | (i >> 32);
68 std::size_t bucket_index(hash_type h)
70 auto index = reverse_bits(h);
74 auto size = m_buckets.size();
75 int bits = std::bit_width(size - 1);
78 hash_type mask = (bits >= (
sizeof(hash_type) * 8)) ? ~hash_type(0) : (hash_type(1) << bits) - 1;
80 auto result = index & mask;
Containers, iterator adapters, callable wrappers, and value utilities.
Definition annex.hpp:14