35template <
typename H,
typename T>
40template <
typename H,
typename T,
typename =
void>
43template <
typename H,
typename T>
46 std::void_t<decltype(PwHashValue(
47 std::declval<H>(), std::declval<const T&>()))>>
48 : std::is_same<decltype(PwHashValue(std::declval<H>(),
49 std::declval<const T&>())),
52template <
typename H,
typename T>
55template <
typename T,
typename =
void>
60 std::void_t<decltype(std::declval<std::hash<T>>()(
61 std::declval<const T&>()))>>
62 : std::is_same<decltype(std::declval<std::hash<T>>()(
63 std::declval<const T&>())),
72template <
typename... Ts>
85template <
typename H,
typename T>
86H hash_value_dispatcher(H h,
const T& val) {
87 if constexpr (kHasPwHashValue<H, T>) {
89 }
else if constexpr (std::is_pointer_v<T> || std::is_null_pointer_v<T>) {
90 return H::mix(std::move(h),
reinterpret_cast<uintptr_t
>(val));
91 }
else if constexpr (std::is_enum_v<T>) {
94 static_cast<size_t>(
static_cast<std::underlying_type_t<T>
>(val)));
95 }
else if constexpr (kIsStdVariant<T>) {
96 h = H::mix(std::move(h), val.index());
98 [&](
const auto& alternative) {
99 return hash_value_dispatcher(std::move(h), alternative);
103 static_assert(kHasStdHash<T>,
104 "The type must be hashable by either PwHashValue, std::hash, "
105 "or a pointer/enum/variant.");
106 return H::mix(std::move(h), std::hash<T>()(val));
137 h.state_ ^= val + 0x9e3779b9 + (h.state_ << 6) + (h.state_ >> 2);
146 template <
typename T>
148 h = hash_impl::hash_value_dispatcher(std::move(h), val);
170 template <
typename T,
typename... Ts>
172 h =
combine(std::move(h), first);
173 if constexpr (
sizeof...(rest) > 0) {
174 return combine(std::move(h), rest...);
193 template <
typename T>
197 for (
size_t i = 0; i < size; i++) {
198 h =
combine(std::move(h), data[i]);
214 template <
typename InputIt>
220 for (
auto it = first; it != last; ++it) {
237 constexpr explicit Hash(
size_t seed = 17) : seed_(seed) {}
239 template <
typename T>
240 constexpr size_t operator()(
const T& value)
const {
241 return hash_impl::hash_value_dispatcher(
HashState(seed_), value).finalize();
247 template <
typename T,
typename U>
248 constexpr bool operator()(
const T& lhs,
const U& rhs)
const {
Definition: functional.h:118
static HashState combine_contiguous(HashState &&h, const T *data, size_t size)
Definition: functional.h:194
static HashState mix(HashState &&h, size_t val)
Definition: functional.h:136
HashState(size_t seed=17)
Definition: functional.h:122
static HashState combine(HashState &&h, const T &first, const Ts &... rest)
Definition: functional.h:171
static HashState combine(HashState &&h, const T &val)
Definition: functional.h:147
static HashState combine_unordered(HashState &&h, InputIt first, InputIt last)
Definition: functional.h:215
size_t finalize()
Finalizes the hash calculation and returns the result.
Definition: functional.h:229
The Pigweed namespace.
Definition: alignment.h:27
H PwHashValue(H h, const T &val)=delete
Definition: functional.h:246
Definition: functional.h:235
Definition: functional.h:41
Definition: functional.h:56
Definition: functional.h:70