|
1 | 1 | #include <CesiumUtility/Hash.h> |
2 | 2 |
|
| 3 | +#include <climits> |
3 | 4 | #include <cstddef> |
4 | 5 | #include <cstdint> |
5 | 6 |
|
@@ -60,43 +61,50 @@ namespace CesiumUtility { |
60 | 61 | // (https://mostlymangling.blogspot.com/2019/12/stronger-better-morer-moremur-better.html) |
61 | 62 | namespace { |
62 | 63 |
|
63 | | -inline uint64_t mix(uint64_t x) { |
64 | | - uint64_t const m = 0xe9846af9b1a615d; |
| 64 | +template <size_t Bits> struct hash_mix_impl; |
65 | 65 |
|
66 | | - x ^= x >> 32; |
67 | | - x *= m; |
68 | | - x ^= x >> 32; |
69 | | - x *= m; |
70 | | - x ^= x >> 28; |
| 66 | +template <> struct hash_mix_impl<64> { |
| 67 | + inline static uint64_t fn(uint64_t x) { |
| 68 | + uint64_t const m = 0xe9846af9b1a615d; |
71 | 69 |
|
72 | | - return x; |
73 | | -} |
| 70 | + x ^= x >> 32; |
| 71 | + x *= m; |
| 72 | + x ^= x >> 32; |
| 73 | + x *= m; |
| 74 | + x ^= x >> 28; |
| 75 | + |
| 76 | + return x; |
| 77 | + } |
| 78 | +}; |
74 | 79 |
|
75 | 80 | // This function is adapted from Boost v1.86.0, `hash_mix_impl<32>` function. |
76 | 81 | // |
77 | 82 | // hash_mix for 32 bit size_t |
78 | 83 | // |
79 | 84 | // We use the "best xmxmx" implementation from |
80 | 85 | // https://github.com/skeeto/hash-prospector/issues/19 |
81 | | -inline uint32_t mix(uint32_t x) { |
82 | | - uint32_t const m1 = 0x21f0aaad; |
83 | | - uint32_t const m2 = 0x735a2d97; |
| 86 | +template <> struct hash_mix_impl<32> { |
| 87 | + inline static uint32_t fn(uint32_t x) { |
| 88 | + uint32_t const m1 = 0x21f0aaad; |
| 89 | + uint32_t const m2 = 0x735a2d97; |
84 | 90 |
|
85 | | - x ^= x >> 16; |
86 | | - x *= m1; |
87 | | - x ^= x >> 15; |
88 | | - x *= m2; |
89 | | - x ^= x >> 15; |
| 91 | + x ^= x >> 16; |
| 92 | + x *= m1; |
| 93 | + x ^= x >> 15; |
| 94 | + x *= m2; |
| 95 | + x ^= x >> 15; |
90 | 96 |
|
91 | | - return x; |
92 | | -} |
| 97 | + return x; |
| 98 | + } |
| 99 | +}; |
93 | 100 |
|
94 | 101 | } // namespace |
95 | 102 |
|
96 | 103 | // This function is adapted from Boost's `hash_combine`. |
97 | 104 | size_t Hash::combine(size_t first, size_t second) { |
98 | 105 | // This will truncate bits on 32-bit builds. |
99 | | - return mix(first + 0x9e3779b9 + second); |
| 106 | + return hash_mix_impl<sizeof(size_t) * CHAR_BIT>::fn( |
| 107 | + first + size_t(0x9e3779b9) + second); |
100 | 108 | } |
101 | 109 |
|
102 | 110 | } // namespace CesiumUtility |
0 commit comments