WPILibC++ 2023.4.3-108-ge5452e3
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 <cassert>
52#include <cstring>
53#include <string>
54#include <tuple>
55#include <utility>
56
57#ifdef _WIN32
58#pragma warning(push)
59#pragma warning(disable : 26495)
60#endif
61
62namespace wpi {
63template <typename T, typename Enable> struct DenseMapInfo;
64
65/// An opaque object representing a hash code.
66///
67/// This object represents the result of hashing some entity. It is intended to
68/// be used to implement hashtables or other hashing-based data structures.
69/// While it wraps and exposes a numeric value, this value should not be
70/// trusted to be stable or predictable across processes or executions.
71///
72/// In order to obtain the hash_code for an object 'x':
73/// \code
74/// using wpi::hash_value;
75/// wpi::hash_code code = hash_value(x);
76/// \endcode
77class hash_code {
78 size_t value;
79
80public:
81 /// Default construct a hash_code.
82 /// Note that this leaves the value uninitialized.
83 hash_code() = default;
84
85 /// Form a hash code directly from a numerical value.
86 hash_code(size_t value) : value(value) {}
87
88 /// Convert the hash code to its numerical value for use.
89 /*explicit*/ operator size_t() const { return value; }
90
91 friend bool operator==(const hash_code &lhs, const hash_code &rhs) {
92 return lhs.value == rhs.value;
93 }
94 friend bool operator!=(const hash_code &lhs, const hash_code &rhs) {
95 return lhs.value != rhs.value;
96 }
97
98 /// Allow a hash_code to be directly run through hash_value.
99 friend size_t hash_value(const hash_code &code) { return code.value; }
100};
101
102/// Compute a hash_code for any integer value.
103///
104/// Note that this function is intended to compute the same hash_code for
105/// a particular value without regard to the pre-promotion type. This is in
106/// contrast to hash_combine which may produce different hash_codes for
107/// differing argument types even if they would implicit promote to a common
108/// type without changing the value.
109template <typename T>
110std::enable_if_t<is_integral_or_enum<T>::value, hash_code> hash_value(T value);
111
112/// Compute a hash_code for a pointer's address.
113///
114/// N.B.: This hashes the *address*. Not the value and not the type.
115template <typename T> hash_code hash_value(const T *ptr);
116
117/// Compute a hash_code for a pair of objects.
118template <typename T, typename U>
119hash_code hash_value(const std::pair<T, U> &arg);
120
121/// Compute a hash_code for a tuple.
122template <typename... Ts>
123hash_code hash_value(const std::tuple<Ts...> &arg);
124
125/// Compute a hash_code for a standard string.
126template <typename T>
127hash_code hash_value(const std::basic_string<T> &arg);
128
129
130/// Override the execution seed with a fixed value.
131///
132/// This hashing library uses a per-execution seed designed to change on each
133/// run with high probability in order to ensure that the hash codes are not
134/// attackable and to ensure that output which is intended to be stable does
135/// not rely on the particulars of the hash codes produced.
136///
137/// That said, there are use cases where it is important to be able to
138/// reproduce *exactly* a specific behavior. To that end, we provide a function
139/// which will forcibly set the seed to a fixed value. This must be done at the
140/// start of the program, before any hashes are computed. Also, it cannot be
141/// undone. This makes it thread-hostile and very hard to use outside of
142/// immediately on start of a simple program designed for reproducible
143/// behavior.
145
146
147// All of the implementation details of actually computing the various hash
148// code values are held within this namespace. These routines are included in
149// the header file mainly to allow inlining and constant propagation.
150namespace hashing {
151namespace detail {
152
153inline uint64_t fetch64(const char *p) {
155 memcpy(&result, p, sizeof(result));
158 return result;
159}
160
161inline uint32_t fetch32(const char *p) {
163 memcpy(&result, p, sizeof(result));
166 return result;
167}
168
169/// Some primes between 2^63 and 2^64 for various uses.
170static constexpr uint64_t k0 = 0xc3a5c85c97cb3127ULL;
171static constexpr uint64_t k1 = 0xb492b66fbe98f273ULL;
172static constexpr uint64_t k2 = 0x9ae16a3b2f90404fULL;
173static constexpr uint64_t k3 = 0xc949d7c7509e6557ULL;
174
175/// Bitwise right rotate.
176/// Normally this will compile to a single instruction, especially if the
177/// shift is a manifest constant.
178inline uint64_t rotate(uint64_t val, size_t shift) {
179 // Avoid shifting by 64: doing so yields an undefined result.
180 return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
181}
182
184 return val ^ (val >> 47);
185}
186
188 // Murmur-inspired hashing.
189 const uint64_t kMul = 0x9ddfea08eb382d69ULL;
190 uint64_t a = (low ^ high) * kMul;
191 a ^= (a >> 47);
192 uint64_t b = (high ^ a) * kMul;
193 b ^= (b >> 47);
194 b *= kMul;
195 return b;
196}
197
198inline uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed) {
199 uint8_t a = s[0];
200 uint8_t b = s[len >> 1];
201 uint8_t c = s[len - 1];
202 uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
203 uint32_t z = static_cast<uint32_t>(len) + (static_cast<uint32_t>(c) << 2);
204 return shift_mix(y * k2 ^ z * k3 ^ seed) * k2;
205}
206
207inline uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed) {
208 uint64_t a = fetch32(s);
209 return hash_16_bytes(len + (a << 3), seed ^ fetch32(s + len - 4));
210}
211
212inline uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed) {
213 uint64_t a = fetch64(s);
214 uint64_t b = fetch64(s + len - 8);
215 return hash_16_bytes(seed ^ a, rotate(b + len, len)) ^ b;
216}
217
218inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) {
219 uint64_t a = fetch64(s) * k1;
220 uint64_t b = fetch64(s + 8);
221 uint64_t c = fetch64(s + len - 8) * k2;
222 uint64_t d = fetch64(s + len - 16) * k0;
223 return hash_16_bytes(rotate(a - b, 43) + rotate(c ^ seed, 30) + d,
224 a + rotate(b ^ k3, 20) - c + len + seed);
225}
226
227inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) {
228 uint64_t z = fetch64(s + 24);
229 uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0;
230 uint64_t b = rotate(a + z, 52);
231 uint64_t c = rotate(a, 37);
232 a += fetch64(s + 8);
233 c += rotate(a, 7);
234 a += fetch64(s + 16);
235 uint64_t vf = a + z;
236 uint64_t vs = b + rotate(a, 31) + c;
237 a = fetch64(s + 16) + fetch64(s + len - 32);
238 z = fetch64(s + len - 8);
239 b = rotate(a + z, 52);
240 c = rotate(a, 37);
241 a += fetch64(s + len - 24);
242 c += rotate(a, 7);
243 a += fetch64(s + len - 16);
244 uint64_t wf = a + z;
245 uint64_t ws = b + rotate(a, 31) + c;
246 uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0);
247 return shift_mix((seed ^ (r * k0)) + vs) * k2;
248}
249
250inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) {
251 if (length >= 4 && length <= 8)
252 return hash_4to8_bytes(s, length, seed);
253 if (length > 8 && length <= 16)
254 return hash_9to16_bytes(s, length, seed);
255 if (length > 16 && length <= 32)
256 return hash_17to32_bytes(s, length, seed);
257 if (length > 32)
258 return hash_33to64_bytes(s, length, seed);
259 if (length != 0)
260 return hash_1to3_bytes(s, length, seed);
261
262 return k2 ^ seed;
263}
264
265/// The intermediate state used during hashing.
266/// Currently, the algorithm for computing hash codes is based on CityHash and
267/// keeps 56 bytes of arbitrary state.
269 uint64_t h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0, h5 = 0, h6 = 0;
270
271 /// Create a new hash_state structure and initialize it based on the
272 /// seed and the first 64-byte chunk.
273 /// This effectively performs the initial mix.
274 static hash_state create(const char *s, uint64_t seed) {
275 hash_state state = {
276 0, seed, hash_16_bytes(seed, k1), rotate(seed ^ k1, 49),
277 seed * k1, shift_mix(seed), 0 };
278 state.h6 = hash_16_bytes(state.h4, state.h5);
279 state.mix(s);
280 return state;
281 }
282
283 /// Mix 32-bytes from the input sequence into the 16-bytes of 'a'
284 /// and 'b', including whatever is already in 'a' and 'b'.
285 static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) {
286 a += fetch64(s);
287 uint64_t c = fetch64(s + 24);
288 b = rotate(b + a + c, 21);
289 uint64_t d = a;
290 a += fetch64(s + 8) + fetch64(s + 16);
291 b += rotate(a, 44) + d;
292 a += c;
293 }
294
295 /// Mix in a 64-byte buffer of data.
296 /// We mix all 64 bytes even when the chunk length is smaller, but we
297 /// record the actual length.
298 void mix(const char *s) {
299 h0 = rotate(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
300 h1 = rotate(h1 + h4 + fetch64(s + 48), 42) * k1;
301 h0 ^= h6;
302 h1 += h3 + fetch64(s + 40);
303 h2 = rotate(h2 + h5, 33) * k1;
304 h3 = h4 * k1;
305 h4 = h0 + h5;
306 mix_32_bytes(s, h3, h4);
307 h5 = h2 + h6;
308 h6 = h1 + fetch64(s + 16);
309 mix_32_bytes(s + 32, h5, h6);
310 std::swap(h2, h0);
311 }
312
313 /// Compute the final 64-bit hash code value based on the current
314 /// state and the length of bytes hashed.
315 uint64_t finalize(size_t length) {
317 hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0);
318 }
319};
320
321
322/// A global, fixed seed-override variable.
323///
324/// This variable can be set using the \see wpi::set_fixed_execution_seed
325/// function. See that function for details. Do not, under any circumstances,
326/// set or read this variable.
328
330 // FIXME: This needs to be a per-execution seed. This is just a placeholder
331 // implementation. Switching to a per-execution seed is likely to flush out
332 // instability bugs and so will happen as its own commit.
333 //
334 // However, if there is a fixed seed override set the first time this is
335 // called, return that instead of the per-execution seed.
336 const uint64_t seed_prime = 0xff51afd7ed558ccdULL;
337 static uint64_t seed = fixed_seed_override ? fixed_seed_override : seed_prime;
338 return seed;
339}
340
341
342/// Trait to indicate whether a type's bits can be hashed directly.
343///
344/// A type trait which is true if we want to combine values for hashing by
345/// reading the underlying data. It is false if values of this type must
346/// first be passed to hash_value, and the resulting hash_codes combined.
347//
348// FIXME: We want to replace is_integral_or_enum and is_pointer here with
349// a predicate which asserts that comparing the underlying storage of two
350// values of the type for equality is equivalent to comparing the two values
351// for equality. For all the platforms we care about, this holds for integers
352// and pointers, but there are platforms where it doesn't and we would like to
353// support user-defined types which happen to satisfy this property.
354template <typename T> struct is_hashable_data
355 : std::integral_constant<bool, ((is_integral_or_enum<T>::value ||
356 std::is_pointer<T>::value) &&
357 64 % sizeof(T) == 0)> {};
358
359// Special case std::pair to detect when both types are viable and when there
360// is no alignment-derived padding in the pair. This is a bit of a lie because
361// std::pair isn't truly POD, but it's close enough in all reasonable
362// implementations for our use case of hashing the underlying data.
363template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
364 : std::integral_constant<bool, (is_hashable_data<T>::value &&
365 is_hashable_data<U>::value &&
366 (sizeof(T) + sizeof(U)) ==
367 sizeof(std::pair<T, U>))> {};
368
369/// Helper to get the hashable data representation for a type.
370/// This variant is enabled when the type itself can be used.
371template <typename T>
372std::enable_if_t<is_hashable_data<T>::value, T>
374 return value;
375}
376/// Helper to get the hashable data representation for a type.
377/// This variant is enabled when we must first call hash_value and use the
378/// result as our data.
379template <typename T>
380std::enable_if_t<!is_hashable_data<T>::value, size_t>
383 return hash_value(value);
384}
385
386/// Helper to store data from a value into a buffer and advance the
387/// pointer into that buffer.
388///
389/// This routine first checks whether there is enough space in the provided
390/// buffer, and if not immediately returns false. If there is space, it
391/// copies the underlying bytes of value into the buffer, advances the
392/// buffer_ptr past the copied bytes, and returns true.
393template <typename T>
394bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
395 size_t offset = 0) {
396 size_t store_size = sizeof(value) - offset;
397 if (buffer_ptr + store_size > buffer_end)
398 return false;
399 const char *value_data = reinterpret_cast<const char *>(&value);
400 memcpy(buffer_ptr, value_data + offset, store_size);
401 buffer_ptr += store_size;
402 return true;
403}
404
405/// Implement the combining of integral values into a hash_code.
406///
407/// This overload is selected when the value type of the iterator is
408/// integral. Rather than computing a hash_code for each object and then
409/// combining them, this (as an optimization) directly combines the integers.
410template <typename InputIteratorT>
411hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
412 const uint64_t seed = get_execution_seed();
413 char buffer[64], *buffer_ptr = buffer;
414 char *const buffer_end = std::end(buffer);
415 while (first != last && store_and_advance(buffer_ptr, buffer_end,
417 ++first;
418 if (first == last)
419 return hash_short(buffer, buffer_ptr - buffer, seed);
420 assert(buffer_ptr == buffer_end);
421
422 hash_state state = state.create(buffer, seed);
423 size_t length = 64;
424 while (first != last) {
425 // Fill up the buffer. We don't clear it, which re-mixes the last round
426 // when only a partial 64-byte chunk is left.
427 buffer_ptr = buffer;
428 while (first != last && store_and_advance(buffer_ptr, buffer_end,
430 ++first;
431
432 // Rotate the buffer if we did a partial fill in order to simulate doing
433 // a mix of the last 64-bytes. That is how the algorithm works when we
434 // have a contiguous byte sequence, and we want to emulate that here.
435 std::rotate(buffer, buffer_ptr, buffer_end);
436
437 // Mix this chunk into the current state.
438 state.mix(buffer);
439 length += buffer_ptr - buffer;
440 };
441
442 return state.finalize(length);
443}
444
445/// Implement the combining of integral values into a hash_code.
446///
447/// This overload is selected when the value type of the iterator is integral
448/// and when the input iterator is actually a pointer. Rather than computing
449/// a hash_code for each object and then combining them, this (as an
450/// optimization) directly combines the integers. Also, because the integers
451/// are stored in contiguous memory, this routine avoids copying each value
452/// and directly reads from the underlying memory.
453template <typename ValueT>
454std::enable_if_t<is_hashable_data<ValueT>::value, hash_code>
456 const uint64_t seed = get_execution_seed();
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);
460 if (length <= 64)
461 return hash_short(s_begin, length, seed);
462
463 const char *s_aligned_end = s_begin + (length & ~63);
464 hash_state state = state.create(s_begin, seed);
465 s_begin += 64;
466 while (s_begin != s_aligned_end) {
467 state.mix(s_begin);
468 s_begin += 64;
469 }
470 if (length & 63)
471 state.mix(s_end - 64);
472
473 return state.finalize(length);
474}
475
476} // namespace detail
477} // namespace hashing
478
479
480/// Compute a hash_code for a sequence of values.
481///
482/// This hashes a sequence of values. It produces the same hash_code as
483/// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences
484/// and is significantly faster given pointers and types which can be hashed as
485/// a sequence of bytes.
486template <typename InputIteratorT>
487hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) {
489}
490
491
492// Implementation details for hash_combine.
493namespace hashing {
494namespace detail {
495
496/// Helper class to manage the recursive combining of hash_combine
497/// arguments.
498///
499/// This class exists to manage the state and various calls involved in the
500/// recursive combining of arguments used in hash_combine. It is particularly
501/// useful at minimizing the code in the recursive calls to ease the pain
502/// caused by a lack of variadic functions.
504 char buffer[64] = {};
507
508public:
509 /// Construct a recursive hash combining helper.
510 ///
511 /// This sets up the state for a recursive hash combine, including getting
512 /// the seed and buffer setup.
515
516 /// Combine one chunk of data into the current in-flight hash.
517 ///
518 /// This merges one chunk of data into the hash. First it tries to buffer
519 /// the data. If the buffer is full, it hashes the buffer into its
520 /// hash_state, empties it, and then merges the new chunk in. This also
521 /// handles cases where the data straddles the end of the buffer.
522 template <typename T>
523 char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) {
524 if (!store_and_advance(buffer_ptr, buffer_end, data)) {
525 // Check for skew which prevents the buffer from being packed, and do
526 // a partial store into the buffer to fill it. This is only a concern
527 // with the variadic combine because that formation can have varying
528 // argument types.
529 size_t partial_store_size = buffer_end - buffer_ptr;
530 memcpy(buffer_ptr, &data, partial_store_size);
531
532 // If the store fails, our buffer is full and ready to hash. We have to
533 // either initialize the hash state (on the first full buffer) or mix
534 // this buffer into the existing hash state. Length tracks the *hashed*
535 // length, not the buffered length.
536 if (length == 0) {
538 length = 64;
539 } else {
540 // Mix this chunk into the current state and bump length up by 64.
542 length += 64;
543 }
544 // Reset the buffer_ptr to the head of the buffer for the next chunk of
545 // data.
546 buffer_ptr = buffer;
547
548 // Try again to store into the buffer -- this cannot fail as we only
549 // store types smaller than the buffer.
550 if (!store_and_advance(buffer_ptr, buffer_end, data,
551 partial_store_size))
552 wpi_unreachable("buffer smaller than stored type");
553 }
554 return buffer_ptr;
555 }
556
557 /// Recursive, variadic combining method.
558 ///
559 /// This function recurses through each argument, combining that argument
560 /// into a single hash.
561 template <typename T, typename ...Ts>
562 hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
563 const T &arg, const Ts &...args) {
564 buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg));
565
566 // Recurse to the next argument.
567 return combine(length, buffer_ptr, buffer_end, args...);
568 }
569
570 /// Base case for recursive, variadic combining.
571 ///
572 /// The base case when combining arguments recursively is reached when all
573 /// arguments have been handled. It flushes the remaining buffer and
574 /// constructs a hash_code.
575 hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) {
576 // Check whether the entire set of values fit in the buffer. If so, we'll
577 // use the optimized short hashing routine and skip state entirely.
578 if (length == 0)
579 return hash_short(buffer, buffer_ptr - buffer, seed);
580
581 // Mix the final buffer, rotating it if we did a partial fill in order to
582 // simulate doing a mix of the last 64-bytes. That is how the algorithm
583 // works when we have a contiguous byte sequence, and we want to emulate
584 // that here.
585 std::rotate(buffer, buffer_ptr, buffer_end);
586
587 // Mix this chunk into the current state.
589 length += buffer_ptr - buffer;
590
591 return state.finalize(length);
592 }
593};
594
595} // namespace detail
596} // namespace hashing
597
598/// Combine values into a single hash_code.
599///
600/// This routine accepts a varying number of arguments of any type. It will
601/// attempt to combine them into a single hash_code. For user-defined types it
602/// attempts to call a \see hash_value overload (via ADL) for the type. For
603/// integer and pointer types it directly combines their data into the
604/// resulting hash_code.
605///
606/// The result is suitable for returning from a user's hash_value
607/// *implementation* for their user-defined type. Consumers of a type should
608/// *not* call this routine, they should instead call 'hash_value'.
609template <typename ...Ts> hash_code hash_combine(const Ts &...args) {
610 // Recursively hash each argument using a helper class.
612 return helper.combine(0, helper.buffer, helper.buffer + 64, args...);
613}
614
615// Implementation details for implementations of hash_value overloads provided
616// here.
617namespace hashing {
618namespace detail {
619
620/// Helper to hash the value of a single integer.
621///
622/// Overloads for smaller integer types are not provided to ensure consistent
623/// behavior in the presence of integral promotions. Essentially,
624/// "hash_value('4')" and "hash_value('0' + 4)" should be the same.
626 // Similar to hash_4to8_bytes but using a seed instead of length.
627 const uint64_t seed = get_execution_seed();
628 const char *s = reinterpret_cast<const char *>(&value);
629 const uint64_t a = fetch32(s);
630 return hash_16_bytes(seed + (a << 3), fetch32(s + 4));
631}
632
633} // namespace detail
634} // namespace hashing
635
636// Declared and documented above, but defined here so that any of the hashing
637// infrastructure is available.
638template <typename T>
639std::enable_if_t<is_integral_or_enum<T>::value, hash_code> hash_value(T value) {
641 static_cast<uint64_t>(value));
642}
643
644// Declared and documented above, but defined here so that any of the hashing
645// infrastructure is available.
646template <typename T> hash_code hash_value(const T *ptr) {
648 reinterpret_cast<uintptr_t>(ptr));
649}
650
651// Declared and documented above, but defined here so that any of the hashing
652// infrastructure is available.
653template <typename T, typename U>
654hash_code hash_value(const std::pair<T, U> &arg) {
655 return hash_combine(arg.first, arg.second);
656}
657
658// Implementation details for the hash_value overload for std::tuple<...>(...).
659namespace hashing {
660namespace detail {
661
662template <typename... Ts, std::size_t... Indices>
663hash_code hash_value_tuple_helper(const std::tuple<Ts...> &arg,
664 std::index_sequence<Indices...>) {
665 return hash_combine(std::get<Indices>(arg)...);
666}
667
668} // namespace detail
669} // namespace hashing
670
671template <typename... Ts>
672hash_code hash_value(const std::tuple<Ts...> &arg) {
673 // TODO: Use std::apply when LLVM starts using C++17.
675 arg, typename std::index_sequence_for<Ts...>());
676}
677
678// Declared and documented above, but defined here so that any of the hashing
679// infrastructure is available.
680template <typename T>
681hash_code hash_value(const std::basic_string<T> &arg) {
682 return hash_combine_range(arg.begin(), arg.end());
683}
684
685template <> struct DenseMapInfo<hash_code, void> {
686 static inline hash_code getEmptyKey() { return hash_code(-1); }
687 static inline hash_code getTombstoneKey() { return hash_code(-2); }
688 static unsigned getHashValue(hash_code val) { return val; }
689 static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
690};
691
692} // namespace wpi
693
694#ifdef _WIN32
695#pragma warning(pop)
696#endif
697
698#endif
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArgReturnType arg() const
Definition: ArrayCwiseUnaryOps.h:66
#define wpi_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:133
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 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:110
\rst A contiguous memory buffer with an optional growing ability.
Definition: core.h:862
Definition: core.h:1240
An opaque object representing a hash code.
Definition: Hashing.h:77
hash_code(size_t value)
Form a hash code directly from a numerical value.
Definition: Hashing.h:86
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:99
friend bool operator==(const hash_code &lhs, const hash_code &rhs)
Definition: Hashing.h:91
friend bool operator!=(const hash_code &lhs, const hash_code &rhs)
Definition: Hashing.h:94
auto ptr(T p) -> const void *
\rst Converts p to const void* for pointer formatting.
Definition: format.h:3823
static const symbolic::SymbolExpr< internal::symbolic_last_tag > last
Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last...
Definition: IndexedViewHelper.h:38
const Scalar & y
Definition: MathFunctions.h:821
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
Definition: IndexedViewHelper.h:81
::uint64_t uint64_t
Definition: Meta.h:58
::uint32_t uint32_t
Definition: Meta.h:56
::uint8_t uint8_t
Definition: Meta.h:52
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
Definition: format-inl.h:32
uint128_t uintptr_t
Definition: format.h:432
result
Definition: format.h:2564
Definition: BFloat16.h:88
void swap(wpi::SmallPtrSet< T, N > &LHS, wpi::SmallPtrSet< T, N > &RHS)
Implement std::swap in terms of SmallPtrSet swap.
Definition: SmallPtrSet.h:512
static constexpr const velocity::meters_per_second_t c(299792458.0)
Speed of light in vacuum.
b
Definition: data.h:44
uint32_t fetch32(const char *p)
Definition: Hashing.h:161
static constexpr uint64_t k1
Definition: Hashing.h:171
uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed)
Definition: Hashing.h:207
hash_code hash_integer_value(uint64_t value)
Helper to hash the value of a single integer.
Definition: Hashing.h:625
std::enable_if_t< is_hashable_data< ValueT >::value, hash_code > hash_combine_range_impl(ValueT *first, ValueT *last)
Implement the combining of integral values into a hash_code.
Definition: Hashing.h:455
hash_code hash_value_tuple_helper(const std::tuple< Ts... > &arg, std::index_sequence< Indices... >)
Definition: Hashing.h:663
uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed)
Definition: Hashing.h:198
uint64_t rotate(uint64_t val, size_t shift)
Bitwise right rotate.
Definition: Hashing.h:178
hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last)
Implement the combining of integral values into a hash_code.
Definition: Hashing.h:411
static constexpr uint64_t k3
Definition: Hashing.h:173
static constexpr uint64_t k2
Definition: Hashing.h:172
uint64_t fixed_seed_override
A global, fixed seed-override variable.
static constexpr uint64_t k0
Some primes between 2^63 and 2^64 for various uses.
Definition: Hashing.h:170
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:373
uint64_t hash_16_bytes(uint64_t low, uint64_t high)
Definition: Hashing.h:187
uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed)
Definition: Hashing.h:212
uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed)
Definition: Hashing.h:227
uint64_t fetch64(const char *p)
Definition: Hashing.h:153
uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed)
Definition: Hashing.h:218
uint64_t get_execution_seed()
Definition: Hashing.h:329
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:394
uint64_t shift_mix(uint64_t val)
Definition: Hashing.h:183
uint64_t hash_short(const char *s, size_t length, uint64_t seed)
Definition: Hashing.h:250
void swapByteOrder(T &Value)
Definition: SwapByteOrder.h:158
constexpr bool IsBigEndianHost
Definition: SwapByteOrder.h:98
Definition: AprilTagFieldLayout.h:18
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:487
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:609
hash_code hash_value(const std::basic_string< T > &arg)
Compute a hash_code for a standard string.
Definition: Hashing.h:681
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:639
void set_fixed_execution_hash_seed(uint64_t fixed_value)
Override the execution seed with a fixed value.
Definition: format.h:1552
static unsigned getHashValue(hash_code val)
Definition: Hashing.h:688
static hash_code getTombstoneKey()
Definition: Hashing.h:687
static bool isEqual(hash_code LHS, hash_code RHS)
Definition: Hashing.h:689
static hash_code getEmptyKey()
Definition: Hashing.h:686
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:49
Helper class to manage the recursive combining of hash_combine arguments.
Definition: Hashing.h:503
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:523
const uint64_t seed
Definition: Hashing.h:506
hash_state state
Definition: Hashing.h:505
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:562
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end)
Base case for recursive, variadic combining.
Definition: Hashing.h:575
char buffer[64]
Definition: Hashing.h:504
hash_combine_recursive_helper()
Construct a recursive hash combining helper.
Definition: Hashing.h:513
The intermediate state used during hashing.
Definition: Hashing.h:268
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:274
uint64_t h2
Definition: Hashing.h:269
uint64_t h3
Definition: Hashing.h:269
uint64_t h6
Definition: Hashing.h:269
uint64_t h5
Definition: Hashing.h:269
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:315
uint64_t h4
Definition: Hashing.h:269
uint64_t h1
Definition: Hashing.h:269
void mix(const char *s)
Mix in a 64-byte buffer of data.
Definition: Hashing.h:298
uint64_t h0
Definition: Hashing.h:269
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:285
Trait to indicate whether a type's bits can be hashed directly.
Definition: Hashing.h:357