Hashing
The <boost/int128/hash.hpp> header provides specializations of std::hash for uint128_t and int128_t, allowing the library types to be used as keys in std::unordered_map, std::unordered_set, and any other container that relies on std::hash.
#include <boost/int128/hash.hpp>
Specializations
namespace std {
template <>
struct hash<boost::int128::int128_t>
{
std::size_t operator()(boost::int128::int128_t v) const noexcept;
};
template <>
struct hash<boost::int128::uint128_t>
{
std::size_t operator()(boost::int128::uint128_t v) const noexcept;
};
} // namespace std
Each 64-bit half of the value is first run through a SplitMix64 finalizer so that every input bit influences the lower bits of the result.
This is necessary because std::hash<std::uint64_t> is permitted to truncate to std::size_t, which would lose the upper 32 bits on 32-bit platforms and cause distinct 128-bit values to collide.
The two finalized halves are then combined with the boost::hash_combine mixing formula.
Guarantees
-
Two values comparing equal under
operator==produce the same hash. -
For any non-zero
v,std::hash<int128_t>{}(v) != std::hash<int128_t>{}(-v). -
The mixing function is asymmetric, so
{high, low}and{low, high}do not collide except by chance. -
The hash value is implementation-defined and may differ across platforms, compilers, or library versions. Do not persist hash values across runs.