Implement std::hash support for evmc_bytes32

Uses FNV1a hash with 64-bit result.
This commit is contained in:
Alex Beregszaszi 2018-09-07 10:40:04 +01:00 committed by Paweł Bylica
parent 3dfa18a393
commit da9c03ffb5
No known key found for this signature in database
GPG Key ID: 7A0C037434FE77EF
1 changed files with 36 additions and 0 deletions

View File

@ -16,6 +16,7 @@
#include <evmc/evmc.h>
#include <cstring>
#include <functional>
/// The comparator for std::map<evmc_address, ...>.
bool operator<(const evmc_address& a, const evmc_address& b)
@ -41,4 +42,39 @@ bool operator==(const evmc_bytes32& a, const evmc_bytes32& b)
return std::memcmp(a.bytes, b.bytes, sizeof(a)) == 0;
}
/// FNV1a hash function with 64-bit result.
static inline uint64_t fnv1a_64(const uint8_t* ptr, size_t len)
{
constexpr uint64_t prime = 1099511628211ULL;
constexpr uint64_t offset_basis = 14695981039346656037ULL;
uint64_t ret = offset_basis;
for (size_t i = 0; i < len; i++)
{
ret ^= ptr[i];
ret *= prime;
}
return ret;
}
static_assert(sizeof(size_t) == sizeof(uint64_t), "size_t is not 64-bit wide");
namespace std
{
/// Hash operator template needed for std::ordered_set and others using hashes.
template <>
struct hash<evmc_bytes32>
{
/// The argument type.
typedef evmc_bytes32 argument_type;
/// The result type.
typedef std::size_t result_type;
/// Hash operator using FNV1a.
result_type operator()(argument_type const& s) const noexcept
{
return fnv1a_64(s.bytes, sizeof(s.bytes));
}
};
} // namespace std
/** @} */