WPILibC++ 2025.2.1
Loading...
Searching...
No Matches
Hashing.h
Go to the documentation of this file.
1//===-- llvm/ADT/Hashing.h - Utilities for hashing --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the newly proposed standard C++ interfaces for hashing
10// arbitrary data and building hash functions for user-defined types. This
11// interface was originally proposed in N3333[1] and is currently under review
12// for inclusion in a future TR and/or standard.
13//
14// The primary interfaces provide are comprised of one type and three functions:
15//
16// -- 'hash_code' class is an opaque type representing the hash code for some
17// data. It is the intended product of hashing, and can be used to implement
18// hash tables, checksumming, and other common uses of hashes. It is not an
19// integer type (although it can be converted to one) because it is risky
20// to assume much about the internals of a hash_code. In particular, each
21// execution of the program has a high probability of producing a different
22// hash_code for a given input. Thus their values are not stable to save or
23// persist, and should only be used during the execution for the
24// construction of hashing datastructures.
25//
26// -- 'hash_value' is a function designed to be overloaded for each
27// user-defined type which wishes to be used within a hashing context. It
28// should be overloaded within the user-defined type's namespace and found
29// via ADL. Overloads for primitive types are provided by this library.
30//
31// -- 'hash_combine' and 'hash_combine_range' are functions designed to aid
32// programmers in easily and intuitively combining a set of data into
33// a single hash_code for their object. They should only logically be used
34// within the implementation of a 'hash_value' routine or similar context.
35//
36// Note that 'hash_combine_range' contains very special logic for hashing
37// a contiguous array of integers or pointers. This logic is *extremely* fast,
38// on a modern Intel "Gainestown" Xeon (Nehalem uarch) @2.2 GHz, these were
39// benchmarked at over 6.5 GiB/s for large keys, and <20 cycles/hash for keys
40// under 32-bytes.
41//
42//===----------------------------------------------------------------------===//
43
44#ifndef WPIUTIL_WPI_HASHING_H
45#define WPIUTIL_WPI_HASHING_H
46
47#include "wpi/ErrorHandling.h"
48#include "wpi/SwapByteOrder.h"
49#include "wpi/type_traits.h"
50#include <algorithm>
51#include <bit>
52#include <cassert>
53#include <cstring>
54#include <optional>
55#include <string>
56#include <tuple>
57#include <utility>
58
59#ifdef _WIN32
60#pragma warning(push)
61#pragma warning(disable : 26495)
62#endif
63
64namespace wpi {
65template <typename T, typename Enable> struct DenseMapInfo;
66
67/// An opaque object representing a hash code.
68///
69/// This object represents the result of hashing some entity. It is intended to
70/// be used to implement hashtables or other hashing-based data structures.
71/// While it wraps and exposes a numeric value, this value should not be
72/// trusted to be stable or predictable across processes or executions.
73///
74/// In order to obtain the hash_code for an object 'x':
75/// \code
76/// using wpi::hash_value;
77/// wpi::hash_code code = hash_value(x);
78/// \endcode
79class hash_code {
80 size_t value;
81
82public:
83 /// Default construct a hash_code.
84 /// Note that this leaves the value uninitialized.
85 hash_code() = default;
86
87 /// Form a hash code directly from a numerical value.
88 hash_code(size_t value) : value(value) {}
89
90 /// Convert the hash code to its numerical value for use.
91 /*explicit*/ operator size_t() const { return value; }
92
93 friend bool operator==(const hash_code &lhs, const hash_code &rhs) {
94 return lhs.value == rhs.value;
95 }
96 friend bool operator!=(const hash_code &lhs, const hash_code &rhs) {
97 return lhs.value != rhs.value;
98 }
99
100 /// Allow a hash_code to be directly run through hash_value.
101 friend size_t hash_value(const hash_code &code) { return code.value; }
102};
103
104/// Compute a hash_code for any integer value.
105///
106/// Note that this function is intended to compute the same hash_code for
107/// a particular value without regard to the pre-promotion type. This is in
108/// contrast to hash_combine which may produce different hash_codes for
109/// differing argument types even if they would implicit promote to a common
110/// type without changing the value.
111template <typename T>
112std::enable_if_t<is_integral_or_enum<T>::value, hash_code> hash_value(T value);
113
114/// Compute a hash_code for a pointer's address.
115///
116/// N.B.: This hashes the *address*. Not the value and not the type.
117template <typename T> hash_code hash_value(const T *ptr);
118
119/// Compute a hash_code for a pair of objects.
120template <typename T, typename U>
121hash_code hash_value(const std::pair<T, U> &arg);
122
123/// Compute a hash_code for a tuple.
124template <typename... Ts>
125hash_code hash_value(const std::tuple<Ts...> &arg);
126
127/// Compute a hash_code for a standard string.
128template <typename T>
129hash_code hash_value(const std::basic_string<T> &arg);
130
131/// Compute a hash_code for a standard string.
132template <typename T> hash_code hash_value(const std::optional<T> &arg);
133
134// All of the implementation details of actually computing the various hash
135// code values are held within this namespace. These routines are included in
136// the header file mainly to allow inlining and constant propagation.
137namespace hashing {
138namespace detail {
139
140inline uint64_t fetch64(const char *p) {
141 uint64_t result;
142 memcpy(&result, p, sizeof(result));
144 sys::swapByteOrder(result);
145 return result;
146}
147
148inline uint32_t fetch32(const char *p) {
149 uint32_t result;
150 memcpy(&result, p, sizeof(result));
152 sys::swapByteOrder(result);
153 return result;
154}
155
156/// Some primes between 2^63 and 2^64 for various uses.
157static constexpr uint64_t k0 = 0xc3a5c85c97cb3127ULL;
158static constexpr uint64_t k1 = 0xb492b66fbe98f273ULL;
159static constexpr uint64_t k2 = 0x9ae16a3b2f90404fULL;
160static constexpr uint64_t k3 = 0xc949d7c7509e6557ULL;
161
162/// Bitwise right rotate.
163/// Normally this will compile to a single instruction, especially if the
164/// shift is a manifest constant.
165inline uint64_t rotate(uint64_t val, size_t shift) {
166 // Avoid shifting by 64: doing so yields an undefined result.
167 return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
168}
169
170inline uint64_t shift_mix(uint64_t val) {
171 return val ^ (val >> 47);
172}
173
174inline uint64_t hash_16_bytes(uint64_t low, uint64_t high) {
175 // Murmur-inspired hashing.
176 const uint64_t kMul = 0x9ddfea08eb382d69ULL;
177 uint64_t a = (low ^ high) * kMul;
178 a ^= (a >> 47);
179 uint64_t b = (high ^ a) * kMul;
180 b ^= (b >> 47);
181 b *= kMul;
182 return b;
183}
184
185inline uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed) {
186 uint8_t a = s[0];
187 uint8_t b = s[len >> 1];
188 uint8_t c = s[len - 1];
189 uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
190 uint32_t z = static_cast<uint32_t>(len) + (static_cast<uint32_t>(c) << 2);
191 return shift_mix(y * k2 ^ z * k3 ^ seed) * k2;
192}
193
194inline uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed) {
195 uint64_t a = fetch32(s);
196 return hash_16_bytes(len + (a << 3), seed ^ fetch32(s + len - 4));
197}
198
199inline uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed) {
200 uint64_t a = fetch64(s);
201 uint64_t b = fetch64(s + len - 8);
202 return hash_16_bytes(seed ^ a, rotate(b + len, len)) ^ b;
203}
204
205inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) {
206 uint64_t a = fetch64(s) * k1;
207 uint64_t b = fetch64(s + 8);
208 uint64_t c = fetch64(s + len - 8) * k2;
209 uint64_t d = fetch64(s + len - 16) * k0;
210 return hash_16_bytes(std::rotr<uint64_t>(a - b, 43) +
211 std::rotr<uint64_t>(c ^ seed, 30) + d,
212 a + std::rotr<uint64_t>(b ^ k3, 20) - c + len + seed);
213}
214
215inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) {
216 uint64_t z = fetch64(s + 24);
217 uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0;
218 uint64_t b = std::rotr<uint64_t>(a + z, 52);
219 uint64_t c = std::rotr<uint64_t>(a, 37);
220 a += fetch64(s + 8);
221 c += std::rotr<uint64_t>(a, 7);
222 a += fetch64(s + 16);
223 uint64_t vf = a + z;
224 uint64_t vs = b + std::rotr<uint64_t>(a, 31) + c;
225 a = fetch64(s + 16) + fetch64(s + len - 32);
226 z = fetch64(s + len - 8);
227 b = std::rotr<uint64_t>(a + z, 52);
228 c = std::rotr<uint64_t>(a, 37);
229 a += fetch64(s + len - 24);
230 c += std::rotr<uint64_t>(a, 7);
231 a += fetch64(s + len - 16);
232 uint64_t wf = a + z;
233 uint64_t ws = b + std::rotr<uint64_t>(a, 31) + c;
234 uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0);
235 return shift_mix((seed ^ (r * k0)) + vs) * k2;
236}
237
238inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) {
239 if (length >= 4 && length <= 8)
240 return hash_4to8_bytes(s, length, seed);
241 if (length > 8 && length <= 16)
242 return hash_9to16_bytes(s, length, seed);
243 if (length > 16 && length <= 32)
244 return hash_17to32_bytes(s, length, seed);
245 if (length > 32)
246 return hash_33to64_bytes(s, length, seed);
247 if (length != 0)
248 return hash_1to3_bytes(s, length, seed);
249
250 return k2 ^ seed;
251}
252
253/// The intermediate state used during hashing.
254/// Currently, the algorithm for computing hash codes is based on CityHash and
255/// keeps 56 bytes of arbitrary state.
257 uint64_t h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0, h5 = 0, h6 = 0;
258
259 /// Create a new hash_state structure and initialize it based on the
260 /// seed and the first 64-byte chunk.
261 /// This effectively performs the initial mix.
262 static hash_state create(const char *s, uint64_t seed) {
263 hash_state state = {0,
264 seed,
265 hash_16_bytes(seed, k1),
266 std::rotr<uint64_t>(seed ^ k1, 49),
267 seed * k1,
268 shift_mix(seed),
269 0};
270 state.h6 = hash_16_bytes(state.h4, state.h5);
271 state.mix(s);
272 return state;
273 }
274
275 /// Mix 32-bytes from the input sequence into the 16-bytes of 'a'
276 /// and 'b', including whatever is already in 'a' and 'b'.
277 static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) {
278 a += fetch64(s);
279 uint64_t c = fetch64(s + 24);
280 b = std::rotr<uint64_t>(b + a + c, 21);
281 uint64_t d = a;
282 a += fetch64(s + 8) + fetch64(s + 16);
283 b += std::rotr<uint64_t>(a, 44) + d;
284 a += c;
285 }
286
287 /// Mix in a 64-byte buffer of data.
288 /// We mix all 64 bytes even when the chunk length is smaller, but we
289 /// record the actual length.
290 void mix(const char *s) {
291 h0 = std::rotr<uint64_t>(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
292 h1 = std::rotr<uint64_t>(h1 + h4 + fetch64(s + 48), 42) * k1;
293 h0 ^= h6;
294 h1 += h3 + fetch64(s + 40);
295 h2 = std::rotr<uint64_t>(h2 + h5, 33) * k1;
296 h3 = h4 * k1;
297 h4 = h0 + h5;
298 mix_32_bytes(s, h3, h4);
299 h5 = h2 + h6;
300 h6 = h1 + fetch64(s + 16);
301 mix_32_bytes(s + 32, h5, h6);
302 std::swap(h2, h0);
303 }
304
305 /// Compute the final 64-bit hash code value based on the current
306 /// state and the length of bytes hashed.
307 uint64_t finalize(size_t length) {
309 hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0);
310 }
311};
312
313/// In LLVM_ENABLE_ABI_BREAKING_CHECKS builds, the seed is non-deterministic
314/// per process (address of a function in LLVMSupport) to prevent having users
315/// depend on the particular hash values. On platforms without ASLR, this is
316/// still likely non-deterministic per build.
317inline uint64_t get_execution_seed() {
318 // Work around x86-64 negative offset folding for old Clang -fno-pic
319 // https://reviews.llvm.org/D93931
320#if LLVM_ENABLE_ABI_BREAKING_CHECKS && \
321 (!defined(__clang__) || __clang_major__ > 11)
322 return static_cast<uint64_t>(
323 reinterpret_cast<uintptr_t>(&install_fatal_error_handler));
324#else
325 return 0xff51afd7ed558ccdULL;
326#endif
327}
328
329
330/// Trait to indicate whether a type's bits can be hashed directly.
331///
332/// A type trait which is true if we want to combine values for hashing by
333/// reading the underlying data. It is false if values of this type must
334/// first be passed to hash_value, and the resulting hash_codes combined.
335//
336// FIXME: We want to replace is_integral_or_enum and is_pointer here with
337// a predicate which asserts that comparing the underlying storage of two
338// values of the type for equality is equivalent to comparing the two values
339// for equality. For all the platforms we care about, this holds for integers
340// and pointers, but there are platforms where it doesn't and we would like to
341// support user-defined types which happen to satisfy this property.
342template <typename T> struct is_hashable_data
343 : std::integral_constant<bool, ((is_integral_or_enum<T>::value ||
344 std::is_pointer<T>::value) &&
345 64 % sizeof(T) == 0)> {};
346
347// Special case std::pair to detect when both types are viable and when there
348// is no alignment-derived padding in the pair. This is a bit of a lie because
349// std::pair isn't truly POD, but it's close enough in all reasonable
350// implementations for our use case of hashing the underlying data.
351template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
352 : std::integral_constant<bool, (is_hashable_data<T>::value &&
353 is_hashable_data<U>::value &&
354 (sizeof(T) + sizeof(U)) ==
355 sizeof(std::pair<T, U>))> {};
356
357/// Helper to get the hashable data representation for a type.
358/// This variant is enabled when the type itself can be used.
359template <typename T>
360std::enable_if_t<is_hashable_data<T>::value, T>
361get_hashable_data(const T &value) {
362 return value;
363}
364/// Helper to get the hashable data representation for a type.
365/// This variant is enabled when we must first call hash_value and use the
366/// result as our data.
367template <typename T>
368std::enable_if_t<!is_hashable_data<T>::value, size_t>
369get_hashable_data(const T &value) {
370 using ::wpi::hash_value;
371 return hash_value(value);
372}
373
374/// Helper to store data from a value into a buffer and advance the
375/// pointer into that buffer.
376///
377/// This routine first checks whether there is enough space in the provided
378/// buffer, and if not immediately returns false. If there is space, it
379/// copies the underlying bytes of value into the buffer, advances the
380/// buffer_ptr past the copied bytes, and returns true.
381template <typename T>
382bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
383 size_t offset = 0) {
384 size_t store_size = sizeof(value) - offset;
385 if (buffer_ptr + store_size > buffer_end)
386 return false;
387 const char *value_data = reinterpret_cast<const char *>(&value);
388 memcpy(buffer_ptr, value_data + offset, store_size);
389 buffer_ptr += store_size;
390 return true;
391}
392
393/// Implement the combining of integral values into a hash_code.
394///
395/// This overload is selected when the value type of the iterator is
396/// integral. Rather than computing a hash_code for each object and then
397/// combining them, this (as an optimization) directly combines the integers.
398template <typename InputIteratorT>
399hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
400 const uint64_t seed = get_execution_seed();
401 char buffer[64], *buffer_ptr = buffer;
402 char *const buffer_end = std::end(buffer);
403 while (first != last && store_and_advance(buffer_ptr, buffer_end,
404 get_hashable_data(*first)))
405 ++first;
406 if (first == last)
407 return hash_short(buffer, buffer_ptr - buffer, seed);
408 assert(buffer_ptr == buffer_end);
409
410 hash_state state = state.create(buffer, seed);
411 size_t length = 64;
412 while (first != last) {
413 // Fill up the buffer. We don't clear it, which re-mixes the last round
414 // when only a partial 64-byte chunk is left.
415 buffer_ptr = buffer;
416 while (first != last && store_and_advance(buffer_ptr, buffer_end,
417 get_hashable_data(*first)))
418 ++first;
419
420 // Rotate the buffer if we did a partial fill in order to simulate doing
421 // a mix of the last 64-bytes. That is how the algorithm works when we
422 // have a contiguous byte sequence, and we want to emulate that here.
423 std::rotate(buffer, buffer_ptr, buffer_end);
424
425 // Mix this chunk into the current state.
426 state.mix(buffer);
427 length += buffer_ptr - buffer;
428 };
429
430 return state.finalize(length);
431}
432
433/// Implement the combining of integral values into a hash_code.
434///
435/// This overload is selected when the value type of the iterator is integral
436/// and when the input iterator is actually a pointer. Rather than computing
437/// a hash_code for each object and then combining them, this (as an
438/// optimization) directly combines the integers. Also, because the integers
439/// are stored in contiguous memory, this routine avoids copying each value
440/// and directly reads from the underlying memory.
441template <typename ValueT>
442std::enable_if_t<is_hashable_data<ValueT>::value, hash_code>
443hash_combine_range_impl(ValueT *first, ValueT *last) {
444 const uint64_t seed = get_execution_seed();
445 const char *s_begin = reinterpret_cast<const char *>(first);
446 const char *s_end = reinterpret_cast<const char *>(last);
447 const size_t length = std::distance(s_begin, s_end);
448 if (length <= 64)
449 return hash_short(s_begin, length, seed);
450
451 const char *s_aligned_end = s_begin + (length & ~63);
452 hash_state state = state.create(s_begin, seed);
453 s_begin += 64;
454 while (s_begin != s_aligned_end) {
455 state.mix(s_begin);
456 s_begin += 64;
457 }
458 if (length & 63)
459 state.mix(s_end - 64);
460
461 return state.finalize(length);
462}
463
464} // namespace detail
465} // namespace hashing
466
467
468/// Compute a hash_code for a sequence of values.
469///
470/// This hashes a sequence of values. It produces the same hash_code as
471/// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences
472/// and is significantly faster given pointers and types which can be hashed as
473/// a sequence of bytes.
474template <typename InputIteratorT>
475hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) {
476 return ::wpi::hashing::detail::hash_combine_range_impl(first, last);
477}
478
479
480// Implementation details for hash_combine.
481namespace hashing {
482namespace detail {
483
484/// Helper class to manage the recursive combining of hash_combine
485/// arguments.
486///
487/// This class exists to manage the state and various calls involved in the
488/// recursive combining of arguments used in hash_combine. It is particularly
489/// useful at minimizing the code in the recursive calls to ease the pain
490/// caused by a lack of variadic functions.
492 char buffer[64] = {};
494 const uint64_t seed;
495
496public:
497 /// Construct a recursive hash combining helper.
498 ///
499 /// This sets up the state for a recursive hash combine, including getting
500 /// the seed and buffer setup.
503
504 /// Combine one chunk of data into the current in-flight hash.
505 ///
506 /// This merges one chunk of data into the hash. First it tries to buffer
507 /// the data. If the buffer is full, it hashes the buffer into its
508 /// hash_state, empties it, and then merges the new chunk in. This also
509 /// handles cases where the data straddles the end of the buffer.
510 template <typename T>
511 char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) {
512 if (!store_and_advance(buffer_ptr, buffer_end, data)) {
513 // Check for skew which prevents the buffer from being packed, and do
514 // a partial store into the buffer to fill it. This is only a concern
515 // with the variadic combine because that formation can have varying
516 // argument types.
517 size_t partial_store_size = buffer_end - buffer_ptr;
518 memcpy(buffer_ptr, &data, partial_store_size);
519
520 // If the store fails, our buffer is full and ready to hash. We have to
521 // either initialize the hash state (on the first full buffer) or mix
522 // this buffer into the existing hash state. Length tracks the *hashed*
523 // length, not the buffered length.
524 if (length == 0) {
526 length = 64;
527 } else {
528 // Mix this chunk into the current state and bump length up by 64.
530 length += 64;
531 }
532 // Reset the buffer_ptr to the head of the buffer for the next chunk of
533 // data.
534 buffer_ptr = buffer;
535
536 // Try again to store into the buffer -- this cannot fail as we only
537 // store types smaller than the buffer.
538 if (!store_and_advance(buffer_ptr, buffer_end, data,
539 partial_store_size))
540 wpi_unreachable("buffer smaller than stored type");
541 }
542 return buffer_ptr;
543 }
544
545 /// Recursive, variadic combining method.
546 ///
547 /// This function recurses through each argument, combining that argument
548 /// into a single hash.
549 template <typename T, typename ...Ts>
550 hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
551 const T &arg, const Ts &...args) {
552 buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg));
553
554 // Recurse to the next argument.
555 return combine(length, buffer_ptr, buffer_end, args...);
556 }
557
558 /// Base case for recursive, variadic combining.
559 ///
560 /// The base case when combining arguments recursively is reached when all
561 /// arguments have been handled. It flushes the remaining buffer and
562 /// constructs a hash_code.
563 hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) {
564 // Check whether the entire set of values fit in the buffer. If so, we'll
565 // use the optimized short hashing routine and skip state entirely.
566 if (length == 0)
567 return hash_short(buffer, buffer_ptr - buffer, seed);
568
569 // Mix the final buffer, rotating it if we did a partial fill in order to
570 // simulate doing a mix of the last 64-bytes. That is how the algorithm
571 // works when we have a contiguous byte sequence, and we want to emulate
572 // that here.
573 std::rotate(buffer, buffer_ptr, buffer_end);
574
575 // Mix this chunk into the current state.
577 length += buffer_ptr - buffer;
578
579 return state.finalize(length);
580 }
581};
582
583} // namespace detail
584} // namespace hashing
585
586/// Combine values into a single hash_code.
587///
588/// This routine accepts a varying number of arguments of any type. It will
589/// attempt to combine them into a single hash_code. For user-defined types it
590/// attempts to call a \see hash_value overload (via ADL) for the type. For
591/// integer and pointer types it directly combines their data into the
592/// resulting hash_code.
593///
594/// The result is suitable for returning from a user's hash_value
595/// *implementation* for their user-defined type. Consumers of a type should
596/// *not* call this routine, they should instead call 'hash_value'.
597template <typename ...Ts> hash_code hash_combine(const Ts &...args) {
598 // Recursively hash each argument using a helper class.
600 return helper.combine(0, helper.buffer, helper.buffer + 64, args...);
601}
602
603// Implementation details for implementations of hash_value overloads provided
604// here.
605namespace hashing {
606namespace detail {
607
608/// Helper to hash the value of a single integer.
609///
610/// Overloads for smaller integer types are not provided to ensure consistent
611/// behavior in the presence of integral promotions. Essentially,
612/// "hash_value('4')" and "hash_value('0' + 4)" should be the same.
613inline hash_code hash_integer_value(uint64_t value) {
614 // Similar to hash_4to8_bytes but using a seed instead of length.
615 const uint64_t seed = get_execution_seed();
616 const char *s = reinterpret_cast<const char *>(&value);
617 const uint64_t a = fetch32(s);
618 return hash_16_bytes(seed + (a << 3), fetch32(s + 4));
619}
620
621} // namespace detail
622} // namespace hashing
623
624// Declared and documented above, but defined here so that any of the hashing
625// infrastructure is available.
626template <typename T>
627std::enable_if_t<is_integral_or_enum<T>::value, hash_code> hash_value(T value) {
628 return ::wpi::hashing::detail::hash_integer_value(
629 static_cast<uint64_t>(value));
630}
631
632// Declared and documented above, but defined here so that any of the hashing
633// infrastructure is available.
634template <typename T> hash_code hash_value(const T *ptr) {
635 return ::wpi::hashing::detail::hash_integer_value(
636 reinterpret_cast<uintptr_t>(ptr));
637}
638
639// Declared and documented above, but defined here so that any of the hashing
640// infrastructure is available.
641template <typename T, typename U>
642hash_code hash_value(const std::pair<T, U> &arg) {
643 return hash_combine(arg.first, arg.second);
644}
645
646template <typename... Ts> hash_code hash_value(const std::tuple<Ts...> &arg) {
647 return std::apply([](const auto &...xs) { return hash_combine(xs...); }, arg);
648}
649
650// Declared and documented above, but defined here so that any of the hashing
651// infrastructure is available.
652template <typename T>
653hash_code hash_value(const std::basic_string<T> &arg) {
654 return hash_combine_range(arg.begin(), arg.end());
655}
656
657template <typename T> hash_code hash_value(const std::optional<T> &arg) {
658 return arg ? hash_combine(true, *arg) : hash_value(false);
659}
660
661template <> struct DenseMapInfo<hash_code, void> {
662 static inline hash_code getEmptyKey() { return hash_code(-1); }
663 static inline hash_code getTombstoneKey() { return hash_code(-2); }
664 static unsigned getHashValue(hash_code val) {
665 return static_cast<unsigned>(size_t(val));
666 }
667 static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
668};
669
670} // namespace wpi
671
672/// Implement std::hash so that hash_code can be used in STL containers.
673namespace std {
674
675template<>
676struct hash<wpi::hash_code> {
677 size_t operator()(wpi::hash_code const& Val) const {
678 return Val;
679 }
680};
681
682} // namespace std;
683
684#ifdef _WIN32
685#pragma warning(pop)
686#endif
687
688#endif
#define wpi_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition ErrorHandling.h:142
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or and nanopb were all modified for use in Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source code
Definition ThirdPartyNotices.txt:123
An opaque object representing a hash code.
Definition Hashing.h:79
hash_code(size_t value)
Form a hash code directly from a numerical value.
Definition Hashing.h:88
hash_code()=default
Default construct a hash_code.
friend size_t hash_value(const hash_code &code)
Allow a hash_code to be directly run through hash_value.
Definition Hashing.h:101
friend bool operator==(const hash_code &lhs, const hash_code &rhs)
Definition Hashing.h:93
friend bool operator!=(const hash_code &lhs, const hash_code &rhs)
Definition Hashing.h:96
auto ptr(T p) -> const void *
Converts p to const void* for pointer formatting.
Definition format.h:3821
detail namespace with internal helper functions
Definition input_adapters.h:32
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
WPI_BASIC_JSON_TPL_DECLARATION void swap(wpi::WPI_BASIC_JSON_TPL &j1, wpi::WPI_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< wpi::WPI_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< wpi::WPI_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.h:5258
uint32_t fetch32(const char *p)
Definition Hashing.h:148
static constexpr uint64_t k1
Definition Hashing.h:158
uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed)
Definition Hashing.h:194
hash_code hash_integer_value(uint64_t value)
Helper to hash the value of a single integer.
Definition Hashing.h:613
uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed)
Definition Hashing.h:185
uint64_t rotate(uint64_t val, size_t shift)
Bitwise right rotate.
Definition Hashing.h:165
hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last)
Implement the combining of integral values into a hash_code.
Definition Hashing.h:399
static constexpr uint64_t k3
Definition Hashing.h:160
static constexpr uint64_t k2
Definition Hashing.h:159
static constexpr uint64_t k0
Some primes between 2^63 and 2^64 for various uses.
Definition Hashing.h:157
std::enable_if_t< is_hashable_data< T >::value, T > get_hashable_data(const T &value)
Helper to get the hashable data representation for a type.
Definition Hashing.h:361
uint64_t hash_16_bytes(uint64_t low, uint64_t high)
Definition Hashing.h:174
uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed)
Definition Hashing.h:199
uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed)
Definition Hashing.h:215
uint64_t fetch64(const char *p)
Definition Hashing.h:140
uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed)
Definition Hashing.h:205
uint64_t get_execution_seed()
In LLVM_ENABLE_ABI_BREAKING_CHECKS builds, the seed is non-deterministic per process (address of a fu...
Definition Hashing.h:317
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.
Definition Hashing.h:382
uint64_t shift_mix(uint64_t val)
Definition Hashing.h:170
uint64_t hash_short(const char *s, size_t length, uint64_t seed)
Definition Hashing.h:238
void swapByteOrder(T &Value)
Definition SwapByteOrder.h:61
constexpr bool IsBigEndianHost
Definition SwapByteOrder.h:26
Foonathan namespace.
Definition ntcore_cpp.h:26
void install_fatal_error_handler(fatal_error_handler_t handler, void *user_data=nullptr)
install_fatal_error_handler - Installs a new error handler to be used whenever a serious (non-recover...
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition Hashing.h:475
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition Hashing.h:597
std::enable_if_t< is_integral_or_enum< T >::value, hash_code > hash_value(T value)
Compute a hash_code for any integer value.
Definition Hashing.h:627
size_t operator()(wpi::hash_code const &Val) const
Definition Hashing.h:677
static unsigned getHashValue(hash_code val)
Definition Hashing.h:664
static hash_code getTombstoneKey()
Definition Hashing.h:663
static bool isEqual(hash_code LHS, hash_code RHS)
Definition Hashing.h:667
static hash_code getEmptyKey()
Definition Hashing.h:662
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition Hashing.h:65
Helper class to manage the recursive combining of hash_combine arguments.
Definition Hashing.h:491
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.
Definition Hashing.h:511
const uint64_t seed
Definition Hashing.h:494
hash_state state
Definition Hashing.h:493
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, const T &arg, const Ts &...args)
Recursive, variadic combining method.
Definition Hashing.h:550
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end)
Base case for recursive, variadic combining.
Definition Hashing.h:563
hash_combine_recursive_helper()
Construct a recursive hash combining helper.
Definition Hashing.h:501
The intermediate state used during hashing.
Definition Hashing.h:256
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.
Definition Hashing.h:262
uint64_t h2
Definition Hashing.h:257
uint64_t h3
Definition Hashing.h:257
uint64_t h6
Definition Hashing.h:257
uint64_t h5
Definition Hashing.h:257
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.
Definition Hashing.h:307
uint64_t h4
Definition Hashing.h:257
uint64_t h1
Definition Hashing.h:257
void mix(const char *s)
Mix in a 64-byte buffer of data.
Definition Hashing.h:290
uint64_t h0
Definition Hashing.h:257
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 ...
Definition Hashing.h:277
Trait to indicate whether a type's bits can be hashed directly.
Definition Hashing.h:345
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Returns a named argument to be used in a formatting function.
Definition base.h:2775