faster std::hash<uuid> implementation
This commit is contained in:
parent
8e9d0f87f5
commit
5458877f2c
@ -526,6 +526,8 @@ namespace uuids
|
|||||||
|
|
||||||
template<class CharT, class Traits, class Allocator>
|
template<class CharT, class Traits, class Allocator>
|
||||||
friend std::basic_string<CharT, Traits, Allocator> to_string(uuid const& id);
|
friend std::basic_string<CharT, Traits, Allocator> to_string(uuid const& id);
|
||||||
|
|
||||||
|
friend std::hash<uuid>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -922,8 +924,39 @@ namespace std
|
|||||||
|
|
||||||
result_type operator()(argument_type const &uuid) const
|
result_type operator()(argument_type const &uuid) const
|
||||||
{
|
{
|
||||||
|
#ifdef UUID_HASH_STRING_BASED
|
||||||
std::hash<std::string> hasher;
|
std::hash<std::string> hasher;
|
||||||
return static_cast<result_type>(hasher(uuids::to_string(uuid)));
|
return static_cast<result_type>(hasher(uuids::to_string(uuid)));
|
||||||
|
#else
|
||||||
|
uint64_t l =
|
||||||
|
static_cast<uint64_t>(uuid.data[0]) << 56 |
|
||||||
|
static_cast<uint64_t>(uuid.data[1]) << 48 |
|
||||||
|
static_cast<uint64_t>(uuid.data[2]) << 40 |
|
||||||
|
static_cast<uint64_t>(uuid.data[3]) << 32 |
|
||||||
|
static_cast<uint64_t>(uuid.data[4]) << 24 |
|
||||||
|
static_cast<uint64_t>(uuid.data[5]) << 16 |
|
||||||
|
static_cast<uint64_t>(uuid.data[6]) << 8 |
|
||||||
|
static_cast<uint64_t>(uuid.data[7]);
|
||||||
|
uint64_t h =
|
||||||
|
static_cast<uint64_t>(uuid.data[8]) << 56 |
|
||||||
|
static_cast<uint64_t>(uuid.data[9]) << 48 |
|
||||||
|
static_cast<uint64_t>(uuid.data[10]) << 40 |
|
||||||
|
static_cast<uint64_t>(uuid.data[11]) << 32 |
|
||||||
|
static_cast<uint64_t>(uuid.data[12]) << 24 |
|
||||||
|
static_cast<uint64_t>(uuid.data[13]) << 16 |
|
||||||
|
static_cast<uint64_t>(uuid.data[14]) << 8 |
|
||||||
|
static_cast<uint64_t>(uuid.data[15]);
|
||||||
|
|
||||||
|
if (sizeof(result_type) > 4)
|
||||||
|
{
|
||||||
|
return result_type(l ^ h);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint64_t hash64 = l ^ h;
|
||||||
|
return result_type(uint32_t(hash64 >> 32) ^ uint32_t(hash64));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -525,7 +525,11 @@ TEST_CASE("Test hashing", "[ops]")
|
|||||||
|
|
||||||
auto h1 = std::hash<std::string>{};
|
auto h1 = std::hash<std::string>{};
|
||||||
auto h2 = std::hash<uuid>{};
|
auto h2 = std::hash<uuid>{};
|
||||||
|
#ifdef UUID_HASH_STRING_BASED
|
||||||
REQUIRE(h1(str) == h2(guid));
|
REQUIRE(h1(str) == h2(guid));
|
||||||
|
#else
|
||||||
|
REQUIRE(h1(str) != h2(guid));
|
||||||
|
#endif
|
||||||
|
|
||||||
auto engine = uuids::uuid_random_generator::engine_type{};
|
auto engine = uuids::uuid_random_generator::engine_type{};
|
||||||
seed_rng(engine);
|
seed_rng(engine);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user