45 #ifndef LLVM_ADT_HASHING_H
46 #define LLVM_ADT_HASHING_H
49 #include "llvm/Support/DataTypes.h"
62 # define __has_feature(x) 0
91 operator size_t()
const {
return value; }
94 return lhs.value == rhs.value;
97 return lhs.value != rhs.value;
111 template <
typename T>
112 typename enable_if<is_integral_or_enum<T>, hash_code>::type
hash_value(
T value);
117 template <
typename T> hash_code
hash_value(
const T *ptr);
120 template <
typename T,
typename U>
121 hash_code
hash_value(
const std::pair<T, U> &arg);
124 template <
typename T>
125 hash_code
hash_value(
const std::basic_string<T> &arg);
153 memcpy(&result, p,
sizeof(result));
161 memcpy(&result, p,
sizeof(result));
168 static const uint64_t
k0 = 0xc3a5c85c97cb3127ULL;
169 static const uint64_t
k1 = 0xb492b66fbe98f273ULL;
170 static const uint64_t
k2 = 0x9ae16a3b2f90404fULL;
171 static const uint64_t
k3 = 0xc949d7c7509e6557ULL;
176 inline uint64_t
rotate(uint64_t val,
size_t shift) {
178 return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
182 return val ^ (val >> 47);
187 const uint64_t kMul = 0x9ddfea08eb382d69ULL;
188 uint64_t a = (low ^ high) * kMul;
190 uint64_t b = (high ^ a) * kMul;
198 uint8_t b = s[len >> 1];
199 uint8_t c = s[len - 1];
200 uint32_t y =
static_cast<uint32_t
>(a) + (static_cast<uint32_t>(b) << 8);
201 uint32_t z = len + (
static_cast<uint32_t
>(c) << 2);
212 uint64_t b =
fetch64(s + len - 8);
222 a +
rotate(b ^
k3, 20) - c + len + seed);
228 uint64_t b =
rotate(a + z, 52);
229 uint64_t c =
rotate(a, 37);
234 uint64_t vs = b +
rotate(a, 31) + c;
243 uint64_t ws = b +
rotate(a, 31) + c;
248 inline uint64_t
hash_short(
const char *s,
size_t length, uint64_t seed) {
249 if (length >= 4 && length <= 8)
251 if (length > 8 && length <= 16)
253 if (length > 16 && length <= 32)
287 b =
rotate(b + a + c, 21);
335 const uint64_t seed_prime = 0xff51afd7ed558ccdULL;
337 : (size_t)seed_prime;
356 is_pointer<T>::value) &&
357 64 % sizeof(T) == 0)> {};
365 is_hashable_data<U>::value &&
366 (sizeof(T) + sizeof(U)) ==
367 sizeof(std::pair<T, U>))> {};
371 template <
typename T>
379 template <
typename T>
393 template <
typename T>
396 size_t store_size =
sizeof(value) - offset;
397 if (buffer_ptr + store_size > buffer_end)
399 const char *value_data =
reinterpret_cast<const char *
>(&value);
400 memcpy(buffer_ptr, value_data + offset, store_size);
401 buffer_ptr += store_size;
410 template <
typename InputIteratorT>
413 char buffer[64], *buffer_ptr = buffer;
419 return hash_short(buffer, buffer_ptr - buffer, seed);
420 assert(buffer_ptr == buffer_end);
424 while (first != last) {
439 length += buffer_ptr - buffer;
453 template <
typename ValueT>
457 const char *s_begin =
reinterpret_cast<const char *
>(first);
458 const char *s_end =
reinterpret_cast<const char *
>(last);
459 const size_t length = std::distance(s_begin, s_end);
463 const char *s_aligned_end = s_begin + (length & ~63);
466 while (s_begin != s_aligned_end) {
471 state.mix(s_end - 64);
473 return state.finalize(length);
486 template <
typename InputIteratorT>
522 template <
typename T>
523 char *
combine_data(
size_t &length,
char *buffer_ptr,
char *buffer_end,
T data) {
529 size_t partial_store_size = buffer_end - buffer_ptr;
530 memcpy(buffer_ptr, &data, partial_store_size);
557 #if defined(__has_feature) && __has_feature(__cxx_variadic_templates__)
563 template <
typename T,
typename ...Ts>
565 const T &arg,
const Ts &...args) {
569 return combine(length, buffer_ptr, buffer_end, args...);
576 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
579 const T1 &arg1,
const T2 &arg2,
const T3 &arg3,
580 const T4 &arg4,
const T5 &arg5,
const T6 &arg6) {
582 return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6);
584 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
586 const T1 &arg1,
const T2 &arg2,
const T3 &arg3,
587 const T4 &arg4,
const T5 &arg5) {
589 return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5);
591 template <
typename T1,
typename T2,
typename T3,
typename T4>
593 const T1 &arg1,
const T2 &arg2,
const T3 &arg3,
596 return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4);
598 template <
typename T1,
typename T2,
typename T3>
600 const T1 &arg1,
const T2 &arg2,
const T3 &arg3) {
602 return combine(length, buffer_ptr, buffer_end, arg2, arg3);
604 template <
typename T1,
typename T2>
606 const T1 &arg1,
const T2 &arg2) {
608 return combine(length, buffer_ptr, buffer_end, arg2);
610 template <
typename T1>
614 return combine(length, buffer_ptr, buffer_end);
638 length += buffer_ptr -
buffer;
648 #if __has_feature(__cxx_variadic_templates__)
661 template <
typename ...Ts> hash_code
hash_combine(
const Ts &...args) {
672 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
675 const T4 &arg4,
const T5 &arg5,
const T6 &arg6) {
678 arg1, arg2, arg3, arg4, arg5, arg6);
680 template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
682 const T4 &arg4,
const T5 &arg5) {
685 arg1, arg2, arg3, arg4, arg5);
687 template <
typename T1,
typename T2,
typename T3,
typename T4>
692 arg1, arg2, arg3, arg4);
694 template <
typename T1,
typename T2,
typename T3>
699 template <
typename T1,
typename T2>
704 template <
typename T1>
726 const char *s =
reinterpret_cast<const char *
>(&value);
736 template <
typename T>
737 typename enable_if<is_integral_or_enum<T>, hash_code>::type
746 reinterpret_cast<uintptr_t>(ptr));
751 template <
typename T,
typename U>
758 template <
typename T>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5)
hash_code hash_value(const std::basic_string< T > &arg)
Compute a hash_code for a standard string.
Helper class to manage the recursive combining of hash_combine arguments.
static const uint64_t k0
Some primes between 2^63 and 2^64 for various uses.
uint64_t shift_mix(uint64_t val)
void set_fixed_execution_hash_seed(size_t fixed_value)
Override the execution seed with a fixed value.
Trait to indicate whether a type's bits can be hashed directly.
hash_code()
Default construct a hash_code. Note that this leaves the value uninitialized.
uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed)
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, const T1 &arg1, const T2 &arg2, const T3 &arg3)
hash_code(size_t value)
Form a hash code directly from a numerical value.
uint64_t finalize(size_t length)
Compute the final 64-bit hash code value based on the current state and the length of bytes hashed...
uint64_t fetch64(const char *p)
static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b)
Mix 32-bytes from the input sequence into the 16-bytes of 'a' and 'b', including whatever is already ...
uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed)
size_t array_lengthof(T(&)[N])
Find the length of an array.
uint64_t rotate(uint64_t val, size_t shift)
Bitwise right rotate. Normally this will compile to a single instruction, especially if the shift is ...
hash_code hash_value(const APFloat &Arg)
uint32_t fetch32(const char *p)
uint64_t hash_16_bytes(uint64_t low, uint64_t high)
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end)
Base case for recursive, variadic combining.
friend bool operator==(const hash_code &lhs, const hash_code &rhs)
void mix(const char *s)
Mix in a 64-byte buffer of data. We mix all 64 bytes even when the chunk length is smaller...
enable_if< is_hashable_data< T >, T >::type get_hashable_data(const T &value)
Helper to get the hashable data representation for a type. This variant is enabled when the type itse...
hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, const T6 &arg6)
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, const T1 &arg1, const T2 &arg2)
static hash_state create(const char *s, uint64_t seed)
Create a new hash_state structure and initialize it based on the seed and the first 64-byte chunk...
uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed)
hash_code hash_integer_value(uint64_t value)
Helper to hash the value of a single integer.
hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last)
Implement the combining of integral values into a hash_code.
uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed)
hash_combine_recursive_helper()
Construct a recursive hash combining helper.
uint64_t hash_short(const char *s, size_t length, uint64_t seed)
unsigned char SwapByteOrder(unsigned char C)
enable_if< is_hashable_data< ValueT >, hash_code >::type hash_combine_range_impl(ValueT *first, ValueT *last)
Implement the combining of integral values into a hash_code.
char * combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data)
Combine one chunk of data into the current in-flight hash.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, const T6 &arg6)
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
An opaque object representing a hash code.
bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T &value, size_t offset=0)
Helper to store data from a value into a buffer and advance the pointer into that buffer...
static const bool IsBigEndianHost
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4)
The intermediate state used during hashing. Currently, the algorithm for computing hash codes is base...
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, const T1 &arg1)
size_t get_execution_seed()
friend size_t hash_value(const hash_code &code)
Allow a hash_code to be directly run through hash_value.
uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed)
size_t fixed_seed_override
A global, fixed seed-override variable.
friend bool operator!=(const hash_code &lhs, const hash_code &rhs)