[util] Specialize util::hash() for more integer types

There was a specialization of util::hash() for uint64_t (which just
returns the integer value), but other integer sizes did not previously
have similar specializations.

Also, two minor semi-related changes to util::map - skip copying empty
nodes when growing the map, and assert that the hash is non-zero when
inserting a new node.
This commit is contained in:
Justin C. Miller
2022-02-28 18:52:18 -08:00
parent f87a4fcd4e
commit 467c2408c4
2 changed files with 7 additions and 1 deletions

View File

@@ -62,10 +62,13 @@ constexpr inline typename types::sized_uint<N>::type hash_fold(typename types::s
template <typename T>
inline uint64_t hash(const T &v) { return fnv1a::hash64(reinterpret_cast<const void*>(&v), sizeof(T)); }
template <> inline uint64_t hash<uint8_t> (const uint8_t &i) { return i; }
template <> inline uint64_t hash<uint16_t>(const uint16_t &i) { return i; }
template <> inline uint64_t hash<uint32_t>(const uint32_t &i) { return i; }
template <> inline uint64_t hash<uint64_t>(const uint64_t &i) { return i; }
template <> inline uint64_t hash<const char *>(const char * const &s) { return fnv1a::hash64_string(s); }
} // namespace util
constexpr inline uint8_t operator "" _id (const char *s, size_t len) { return util::fnv1a::hash64_const(s); }
constexpr inline uint64_t operator "" _id (const char *s, size_t len) { return util::fnv1a::hash64_const(s); }
constexpr inline uint8_t operator "" _id8 (const char *s, size_t len) { return util::hash_fold<8>(util::fnv1a::hash32_const(s)); }

View File

@@ -171,6 +171,7 @@ protected:
for (size_t i = 0; i < count; ++i) {
node &n = old[i];
if (!n.hash()) continue;
insert_node(n.hash(), std::move(n.key), std::move(n.val));
n.~node();
}
@@ -183,6 +184,8 @@ protected:
}
node * insert_node(uint64_t h, K &&k, V &&v) {
assert(h);
size_t i = mod(h);
size_t dist = 0;