00001
00002
00003
00004
00005
00006
00007
00008 #ifndef CK128BITHASH_H_
00009 #define CK128BITHASH_H_
00010
00011 #include "converse.h"
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if !defined __GLIBCXX_TYPE_INT_N_0
00025 namespace std {
00026 template<> struct hash<CmiUInt16> {
00027 using argument_type = CmiUInt16;
00028 using result_type = std::size_t;
00029 static_assert(sizeof(CmiUInt16) == 16, "128-bit integers are not supported");
00030
00031 CMI_FORCE_INLINE
00032 result_type operator()(argument_type data) const {
00033 const argument_type mask = static_cast<std::size_t>(-1);
00034 const auto a = static_cast<std::size_t>(data & mask);
00035 const auto b = static_cast<std::size_t>((data & (mask << 64)) >> 64);
00036 return hash_len_16(a, rotate_by_at_least_1(b + 16, 16)) ^ b;
00037 }
00038 CMI_FORCE_INLINE
00039 result_type rotate_by_at_least_1(std::size_t val, int shift) const {
00040 return (val >> shift) | (val << (64 - shift));
00041 }
00042 CMI_FORCE_INLINE
00043 result_type hash_len_16(std::size_t u, std::size_t v) const {
00044 const std::size_t mul = 0x9ddfea08eb382d69ULL;
00045 auto a = (u ^ v) * mul;
00046 a ^= (a >> 47);
00047 auto b = (v ^ a) * mul;
00048 b ^= (b >> 47);
00049 return b * mul;
00050 }
00051 };
00052 }
00053 #endif
00054
00055 #endif