19 #ifndef ABSL_HASH_INTERNAL_HASH_H_ 20 #define ABSL_HASH_INTERNAL_HASH_H_ 27 #include <forward_list> 37 #include <type_traits> 53 namespace hash_internal {
102 template <
typename T,
typename... Ts>
103 static H
combine(H state,
const T&
value,
const Ts&... values);
118 template <
typename T>
155 template <
typename T,
typename Enable =
void>
169 template <
typename Integral>
171 Integral, typename
std::enable_if<std::is_integral<Integral>::value>::type>
184 template <
typename H,
typename T>
186 const unsigned char* start =
reinterpret_cast<const unsigned char*
>(&
value);
187 return H::combine_contiguous(
std::move(hash_state), start,
sizeof(value));
203 template <
typename H,
typename B>
205 H hash_state, B
value) {
207 static_cast<unsigned char>(value ? 1 : 0));
211 template <
typename H,
typename Enum>
213 H hash_state,
Enum e) {
220 static_cast<typename std::underlying_type<Enum>::type
>(e));
223 template <
typename H,
typename Float>
229 value == 0 ? 0 : value);
236 template <
typename H,
typename LongDouble>
239 const int category = std::fpclassify(value);
243 hash_state = H::combine(
std::move(hash_state), std::signbit(value));
260 auto mantissa =
static_cast<double>(std::frexp(value, &exp));
264 return H::combine(
std::move(hash_state), category);
268 template <
typename H,
typename T>
270 auto v =
reinterpret_cast<uintptr_t
>(
ptr);
279 template <
typename H>
281 return H::combine(
std::move(hash_state), static_cast<void*>(
nullptr));
292 template <
typename T>
296 template <
typename H,
typename T1,
typename T2>
300 return H::combine(
std::move(hash_state), p.first, p.second);
307 template <
typename H,
typename Tuple,
size_t... Is>
309 return H::combine(
std::move(hash_state), std::get<Is>(t)...);
313 template <
typename H,
typename... Ts>
314 #if defined(_MSC_VER) 319 typename std::enable_if<absl::conjunction<is_hashable<Ts>...>
::value, H>::type
331 template <
typename H,
typename T,
typename D>
333 return H::combine(
std::move(hash_state), ptr.get());
337 template <
typename H,
typename T>
339 return H::combine(
std::move(hash_state), ptr.get());
359 template <
typename H>
371 template <
typename H,
typename T,
size_t N>
373 H hash_state,
const std::array<T, N>& array) {
374 return H::combine_contiguous(
std::move(hash_state), array.data(),
379 template <
typename H,
typename T,
typename Allocator>
381 H hash_state,
const std::deque<T, Allocator>& deque) {
384 for (
const auto& t : deque) {
385 hash_state = H::combine(
std::move(hash_state), t);
387 return H::combine(
std::move(hash_state), deque.size());
391 template <
typename H,
typename T,
typename Allocator>
393 H hash_state,
const std::forward_list<T, Allocator>& list) {
395 for (
const T& t : list) {
396 hash_state = H::combine(
std::move(hash_state), t);
399 return H::combine(
std::move(hash_state), size);
403 template <
typename H,
typename T,
typename Allocator>
405 H hash_state,
const std::list<T, Allocator>& list) {
406 for (
const auto& t : list) {
407 hash_state = H::combine(
std::move(hash_state), t);
409 return H::combine(
std::move(hash_state), list.size());
416 template <
typename H,
typename T,
typename Allocator>
420 return H::combine(H::combine_contiguous(
std::move(hash_state), vector.data(),
430 template <
typename H,
typename Key,
typename T,
typename Compare,
434 AbslHashValue(H hash_state,
const std::map<Key, T, Compare, Allocator>& map) {
435 for (
const auto& t : map) {
436 hash_state = H::combine(
std::move(hash_state), t);
438 return H::combine(
std::move(hash_state), map.size());
442 template <
typename H,
typename Key,
typename T,
typename Compare,
447 const std::multimap<Key, T, Compare, Allocator>& map) {
448 for (
const auto& t : map) {
449 hash_state = H::combine(
std::move(hash_state), t);
451 return H::combine(
std::move(hash_state), map.size());
455 template <
typename H,
typename Key,
typename Compare,
typename Allocator>
457 H hash_state,
const std::set<Key, Compare, Allocator>&
set) {
458 for (
const auto& t :
set) {
459 hash_state = H::combine(
std::move(hash_state), t);
465 template <
typename H,
typename Key,
typename Compare,
typename Allocator>
467 H hash_state,
const std::multiset<Key, Compare, Allocator>&
set) {
468 for (
const auto& t :
set) {
469 hash_state = H::combine(
std::move(hash_state), t);
479 template <
typename H,
typename T>
482 if (opt) hash_state = H::combine(
std::move(hash_state), *opt);
487 template <
typename H>
490 template <
typename T>
492 return H::combine(
std::move(hash_state), t);
497 template <
typename H,
typename... T>
498 typename std::enable_if<conjunction<is_hashable<T>...>
::value, H>::type
500 if (!v.valueless_by_exception()) {
503 return H::combine(
std::move(hash_state), v.index());
521 template <
typename H,
typename T>
524 const auto* bytes =
reinterpret_cast<const unsigned char*
>(
data);
525 return H::combine_contiguous(
std::move(hash_state), bytes,
sizeof(T) * size);
529 template <
typename H,
typename T>
532 for (
const auto end = data + size; data <
end; ++
data) {
533 hash_state = H::combine(
std::move(hash_state), *data);
538 #if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE) && \ 539 ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 540 #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 1 542 #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 0 559 using State::HashStateBase::combine_contiguous;
563 template <
typename H,
typename T>
571 template <
typename H,
typename T>
581 #if ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 582 template <
typename H,
typename T>
585 decltype(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE::hash<T>()(value)),
590 ABSL_INTERNAL_LEGACY_HASH_NAMESPACE::hash<T>{}(
value));
592 #endif // ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 596 template <
typename H,
typename T>
603 template <
typename Hash,
typename T>
606 template <
typename H,
typename = decltype(
H::Invoke(
607 std::declval<State>(), std::declval<const T&>()))>
608 static std::true_type Test(
int);
609 template <
typename U>
610 static std::false_type Test(
char);
613 static constexpr
bool value = decltype(Test<Hash>(0))::value;
619 template <
typename T>
628 template <
typename T>
630 : std::integral_constant<bool, HashSelect::template Apply<T>::value> {};
636 #ifdef ABSL_HAVE_INTRINSIC_INT128 638 #else // ABSL_HAVE_INTRINSIC_INT128 640 #endif // ABSL_HAVE_INTRINSIC_INT128 642 static constexpr uint64_t kMul =
643 sizeof(size_t) == 4 ? uint64_t{0xcc9e2d51} : uint64_t{0x9ddfea08eb382d69};
645 template <
typename T>
659 const unsigned char* first,
662 CombineContiguousImpl(hash_state.
state_, first, size,
663 std::integral_constant<
int,
sizeof(
size_t)>{}));
665 using CityHashState::HashStateBase::combine_contiguous;
676 return static_cast<size_t>(Mix(Seed(), static_cast<uint64_t>(value)));
681 static size_t hash(
const T& value) {
702 static uint64_t CombineContiguousImpl(uint64_t state,
703 const unsigned char* first,
size_t len,
704 std::integral_constant<int, 4>
706 static uint64_t CombineContiguousImpl(uint64_t state,
707 const unsigned char* first,
size_t len,
708 std::integral_constant<int, 8>
714 static std::pair<uint64_t, uint64_t>
Read9To16(
const unsigned char* p,
721 static uint64_t
Read4To8(
const unsigned char* p,
size_t len) {
728 static uint32_t
Read1To3(
const unsigned char* p,
size_t len) {
729 return static_cast<uint32_t
>((p[0]) |
730 (p[len / 2] << (len / 2 * 8)) |
731 (p[len - 1] << ((len - 1) * 8)));
741 MultType m = state +
v;
743 return static_cast<uint64_t
>(m ^ (m >> (
sizeof(m) * 8 / 2)));
763 return static_cast<uint64_t
>(
reinterpret_cast<uintptr_t
>(kSeed));
772 uint64_t state,
const unsigned char* first,
size_t len,
773 std::integral_constant<int, 4> ) {
779 }
else if (len >= 4) {
780 v = Read4To8(first, len);
781 }
else if (len > 0) {
782 v = Read1To3(first, len);
787 return Mix(state, v);
792 uint64_t state,
const unsigned char* first,
size_t len,
793 std::integral_constant<int, 8> ) {
799 }
else if (len > 8) {
800 auto p = Read9To16(first, len);
801 state = Mix(state, p.first);
803 }
else if (len >= 4) {
804 v = Read4To8(first, len);
805 }
else if (len > 0) {
806 v = Read1To3(first, len);
811 return Mix(state, v);
828 template <
typename T>
833 template <
typename T>
837 template <
typename H>
838 template <
typename T,
typename... Ts>
846 template <
typename H>
847 template <
typename T>
854 #endif // ABSL_HASH_INTERNAL_HASH_H_
static CityHashState combine_contiguous(CityHashState hash_state, const unsigned char *first, size_t size)
std::enable_if< is_uniquely_represented< T >::value, H >::type hash_range_or_bytes(H hash_state, const T *data, size_t size)
std::enable_if< std::is_same< B, bool >::value, H >::type AbslHashValue(H hash_state, B value)
static ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t Seed()
static auto Invoke(H state, const T &value) -> absl::enable_if_t< std::is_same< H, decltype(AbslHashValue(std::move(state), value))>::value, H >
static auto Invoke(H state, const T &value) -> absl::enable_if_t< is_uniquely_represented< T >::value, H >
uint32_t CityHash32(const char *s, size_t len)
uint64_t Load64(const void *p)
H hash_bytes(H hash_state, const T &value)
#define ABSL_ATTRIBUTE_ALWAYS_INLINE
static uint64_t Read4To8(const unsigned char *p, size_t len)
static uint64_t CombineContiguousImpl(uint64_t state, const unsigned char *first, size_t len, std::integral_constant< int, 4 >)
size_t operator()(const T &value) const
static const void *const kSeed
static H combine(H state, const T &value, const Ts &... values)
static uint32_t Read1To3(const unsigned char *p, size_t len)
uint32_t Load32(const void *p)
static auto Invoke(H state, const T &value) -> absl::enable_if_t< type_traits_internal::IsHashable< T >::value, H >
std::pair< uint64_t, uint64_t > uint128
static ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t Mix(uint64_t state, uint64_t v)
static H combine_contiguous(H state, const T *data, size_t size)
make_integer_sequence< size_t, N > make_index_sequence
uint64_t CityHash64(const char *s, size_t len)
constexpr size_type size() const noexcept
typename std::conditional< B, T, F >::type conditional_t
typename std::enable_if< B, T >::type enable_if_t
static char data[kDataSize]
CityHashState(uint64_t state)
constexpr bool has_value() const noexcept
static size_t hash(T value)
H operator()(const T &t) const
H hash_tuple(H hash_state, const Tuple &t, absl::index_sequence< Is... >)
variant_internal::VisitResult< Visitor, Variants... > visit(Visitor &&vis, Variants &&... vars)
static std::pair< uint64_t, uint64_t > Read9To16(const unsigned char *p, size_t len)
constexpr const_pointer data() const noexcept
InvokeT< F, Args... > Invoke(F &&f, Args &&... args)
static size_t hash(const T &value)
std::shared_ptr< AllocState > state_
static H combine(H state)
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
int Compare(const BigUnsigned< N > &lhs, const BigUnsigned< M > &rhs)