header_utils
Loading...
Searching...
No Matches
hashes.h
1
4
5#pragma once
6
7#ifdef __cpp_consteval
8#include "source_location.h"
9#endif
10#include "bytes.h"
11#include "bits.h"
12#include <array>
13#include <bit>
14
15namespace ghassanpl
16{
20
21 static constexpr inline uint32_t crc32_table[256] = {
22 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
23 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
24 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
25 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
26 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
27 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
28 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
29 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
30 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
31 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
32 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
33 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
34 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
35 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
36 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
37 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
38 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
39 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
40 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
41 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
42 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
43 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
44 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
45 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
46 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
47 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
48 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
49 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
50 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
51 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
52 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
53 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
54 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
55 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
56 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
57 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
58 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
59 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
60 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
61 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
62 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
63 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
64 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
65 };
66
69 template <bytelike_range RANGE>
70 [[nodiscard]] constexpr uint32_t crc32(RANGE&& bytes)
71 {
74 uint32_t crc = 0xFFFFFFFFu;
75 for (auto byte: bytes)
76 crc = crc32_table[(crc ^ to_u8(byte)) & 0xFF] ^ (crc >> 8);
77 return ~crc;
78 }
79
82 template <bytelike... BYTES>
83 [[nodiscard]] constexpr uint32_t crc32(BYTES... bytes)
84 {
85 uint32_t crc = 0xFFFFFFFFu;
86 ((crc = crc32_table[(crc ^ to_u8(bytes)) & 0xFF] ^ (crc >> 8)), ...);
87 return ~crc;
88 }
89
90#ifdef __cpp_consteval
93 [[nodiscard]] constexpr auto crc32(const source_location& k)
94 {
95 return crc32(std::string_view{ k.file_name() }) ^ k.line() ^ k.column();
96 }
97#endif
98
99 static constexpr inline uint64_t crc64_table[256] = {
100 0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5, 0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A,
101 0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B, 0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4,
102 0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A, 0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285,
103 0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4, 0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B,
104 0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8, 0x0B6BD3C3DBFD506B, 0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4,
105 0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5, 0x172F5B3033043EBF, 0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A,
106 0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584, 0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B,
107 0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A, 0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5,
108 0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A, 0x93366450E42ECDF0, 0xD1C685BB4DC4FB63, 0x16D7A787B7FAA0D6, 0x5427466C1E109645,
109 0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324, 0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB,
110 0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75, 0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA,
111 0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB, 0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87, 0xA07CF2199274CA14,
112 0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144, 0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B,
113 0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA, 0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425,
114 0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB, 0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874,
115 0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15, 0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA,
116 0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E, 0x731B26172EE619EB, 0x31EBC7FC870C2F78, 0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7,
117 0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6, 0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19,
118 0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97, 0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648,
119 0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA, 0xC5B073890B687329, 0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6,
120 0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6, 0x73B3727A52B393CC, 0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879,
121 0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18, 0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7,
122 0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149, 0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96,
123 0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7, 0x87E8C60FDED7CF9D, 0xC51827E4773DF90E, 0x020905D88D03A2BB, 0x40F9E43324E99428,
124 0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57, 0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288,
125 0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9, 0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36,
126 0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8, 0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4, 0xC4E0DB53F3C36767,
127 0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206, 0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9,
128 0xE085162AB69D5E3C, 0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589, 0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956,
129 0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37, 0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8,
130 0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066, 0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9,
131 0x14DEA25F3AF9026D, 0x562E43B4931334FE, 0x913F6188692D6F4B, 0xD3CF8063C0C759D8, 0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507,
132 };
133
135 template <bytelike_range RANGE>
136 [[nodiscard]] constexpr uint64_t crc64(RANGE&& bytes)
137 {
138 uint64_t crc = 0;
139 for (auto byte : bytes)
140 crc = crc64_table[crc >> 56] ^ ((crc << 8U) ^ to_u8(byte));
141 return ~crc;
142 }
143
145 template <bytelike... BYTES>
146 [[nodiscard]] constexpr uint64_t crc64(BYTES... bytes)
147 {
148 uint64_t crc = 0;
149 ((crc = crc64_table[crc >> 56] ^ ((crc << 8U) ^ to_u8(bytes))), ...);
150 return ~crc;
151 }
152
153#ifdef __cpp_consteval
155 [[nodiscard]] constexpr auto crc64(const source_location& k)
156 {
157 return crc64(std::string_view{ k.file_name() }) ^ k.line() ^ k.column();
158 }
159
160 struct crc64_hasher
161 {
162 constexpr uint64_t operator()(source_location const& l) const { return crc64(l); }
163 };
164#endif
165
166 // TODO: Add support for non-64bit hashes to all the functions below, especially since
167 // std::hash operates on size_t
168
170 template <bytelike_range RANGE>
171 [[nodiscard]] constexpr uint64_t fnv64(RANGE&& bytes)
172 {
173 uint64_t result = 0xcbf29ce484222325;
174 for (auto byte : bytes)
175 result = (result ^ to_u8(byte)) * 0x00000100000001b3U;
176 return result;
177 }
178
180 template <bytelike... BYTES>
181 [[nodiscard]] constexpr uint64_t fnv64(BYTES... bytes)
182 {
183 uint64_t result = 0xcbf29ce484222325;
184 ((result = (result ^ to_u8(bytes)) * 0x00000100000001b3U), ...);
185 return result;
186 }
187
189 namespace integer
190 {
191 struct splitmix64_state { uint64_t state{}; };
193 [[nodiscard]] constexpr uint64_t splitmix64(splitmix64_state& state, uint64_t stream_id = 0x9e3779b97f4a7c15)
194 {
195 state.state = state.state + stream_id;
196 uint64_t z = state.state;
197 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
198 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
199 z = z ^ (z >> 31);
200 return z;
201 }
202
204 [[nodiscard]] constexpr uint64_t splitmix64(uint64_t seed, uint64_t index, uint64_t stream_id = 0x9e3779b97f4a7c15)
205 {
206 uint64_t z = seed + index * stream_id;
207 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
208 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
209 z = z ^ (z >> 31);
210 return z;
211 }
212
214 [[nodiscard]] constexpr uint64_t murmurhash64(uint64_t k)
215 {
216 k ^= k >> 33;
217 k *= 0xff51afd7ed558ccdULL;
218 k ^= k >> 33;
219 k *= 0xc4ceb9fe1a85ec53ULL;
220 k ^= k >> 33;
221 return k;
222 }
223
225 [[nodiscard]] constexpr uint64_t murmurhash64_2(uint64_t x, uint64_t y)
226 {
227 constexpr auto kMul = 0x9ddfea08eb382d69ULL;
228 auto a = (x ^ y) * kMul;
229 a ^= (a >> 47);
230 auto b = (y ^ a) * kMul;
231 b ^= (b >> 47);
232 b *= kMul;
233 return b;
234 }
235
237 [[nodiscard]] constexpr uint32_t triple32(uint32_t x)
238 {
239 x ^= x >> 17;
240 x *= 0xed5ad4bbU;
241 x ^= x >> 11;
242 x *= 0xac4c1b51U;
243 x ^= x >> 15;
244 x *= 0x31848babU;
245 x ^= x >> 14;
246 return x;
247 }
248 }
249
251 constexpr void fold_in_hash64(uint64_t& hash1, uint64_t hash2) noexcept
252 {
253 constexpr uint64_t kMul = 0x9ddfea08eb382d69ULL;
254 const auto seed = hash1;
255 uint64_t a = (hash2 ^ seed) * kMul;
256 a ^= (a >> 47);
257 uint64_t b = (seed ^ a) * kMul;
258 b ^= (b >> 47);
259 b *= kMul;
260 hash1 = b;
261 }
262
264 template <typename T, typename HASHER = std::hash<std::remove_cvref_t<T>>>
265 constexpr void hash64_combine_to(uint64_t& seed, T&& v, HASHER&& hasher = HASHER{})
266 {
267 auto result = hasher(v);
268 static_assert(std::is_same_v<decltype(result), uint64_t>, "hasher() must return a uint64_t");
269 fold_in_hash64(seed, result);
270 }
271
273 template <template<typename> typename HASHER = std::hash, typename FIRST, typename... T>
274 [[nodiscard]] constexpr uint64_t hash64(FIRST const& first, T&&... values)
275 {
276 auto hasher = HASHER<FIRST>{};
277
278 static_assert(
279 std::is_same_v<decltype(std::declval<HASHER<std::remove_cvref_t<FIRST>>>()(std::declval<FIRST>())), uint64_t> &&
280 (std::is_same_v<decltype(std::declval<HASHER<std::remove_cvref_t<T>>>()(std::declval<T>())), uint64_t> && ... && true),
281 "hasher() must return a uint64_t for each type");
282
283 uint64_t result = hasher(first);
284#if !defined(MSVC_BUG_11047635)
285 auto func = [&result]<typename U>(U&& value) {
286 ghassanpl::hash64_combine_to(result, std::forward<U>(value), HASHER<std::remove_cvref_t<U>>{});
287 };
288 (func(std::forward<T>(values)), ...);
289#else
290 (ghassanpl::hash64_combine_to(result, std::forward<T>(values), HASHER<std::remove_cvref_t<T>>{}), ...);
291#endif
292 return result;
293 }
294
296 template<typename It, typename HASHER = std::hash<std::iter_value_t<It>>>
297 constexpr void fold_in_hash64_range(uint64_t& seed, It first, It last, HASHER const& hasher = {})
298 {
299 static_assert(std::same_as<decltype(hasher(std::declval<std::iter_value_t<It>>())), uint64_t>, "hasher() must return a uint64_t");
300 for (; first != last; ++first)
301 hash64_combine_to(seed, *first, hasher);
302 }
303
305 template<typename It, typename HASHER = std::hash<std::iter_value_t<It>>>
306 [[nodiscard]] constexpr uint64_t hash64_range(It first, It last, HASHER&& hasher = {})
307 {
308 static_assert(std::same_as<decltype(hasher(std::declval<std::iter_value_t<It>>())), uint64_t>, "hasher() must return a uint64_t");
309 uint64_t seed = 0;
310 fold_in_hash64_range(seed, first, last, std::forward<HASHER>(hasher));
311 return seed;
312 }
313
315 template <std::ranges::range T, typename HASHER = std::hash<std::ranges::range_value_t<T>>>
316 [[nodiscard]] constexpr uint64_t hash64_range(T range, HASHER&& hasher = {})
317 {
318 static_assert(std::same_as<decltype(hasher(std::declval<std::ranges::range_value_t<T>>())), uint64_t>, "hasher() must return a uint64_t");
319 uint64_t seed = 0;
320 fold_in_hash64_range(seed, std::ranges::begin(range), std::ranges::end(range), std::forward<HASHER>(hasher));
321 return seed;
322 }
323
324
327
328 template <typename T>
329 requires (sizeof(T) <= sizeof(uint64_t)) &&
330 ((sizeof(T) & (sizeof(T) - 1)) == 0) &&
331 std::is_trivially_copyable_v<T>
332 [[nodiscard]] consteval uint64_t ce_hash64(T val) noexcept
333 {
334 static_assert(!std::is_pointer_v<T>, "cannot hash pointers at compile-time");
335 if constexpr (std::floating_point<T>)
336 {
337 if (val == T{ 0 }) val = T{ 0 };
338 }
339 const auto as_int = std::bit_cast<uintN_t<bit_count<T>>>(val);
340 const auto as_array = to_u8_array(as_int);
341 return fnv64(as_array);
342 }
343
344 template <bytelike T>
345 [[nodiscard]] consteval uint64_t ce_hash64(std::basic_string_view<T> const& val) noexcept { return fnv64(val); }
346
347 template <typename FIRST, typename... T>
348 requires (sizeof...(T) > 0)
349 [[nodiscard]] consteval uint64_t ce_hash64(FIRST const& first, T const&... values)
350 {
351 uint64_t result = ce_hash64(first);
352 (fold_in_hash64(result, ce_hash64(values)), ...);
353 return result;
354 }
355
356 template <typename TUPLE_TYPE, uint64_t... Is>
357 consteval void ce_hash64_tuple_elements(uint64_t& hash, TUPLE_TYPE const& t, std::index_sequence<Is...>)
358 {
359 (fold_in_hash64(hash, ce_hash64(std::get<Is>(t))), ...);
360 }
361
362 template <typename... T>
363 [[nodiscard]] consteval uint64_t ce_hash64(std::tuple<T...> const& tupl) noexcept
364 {
365 uint64_t result = 0;
366 ce_hash64_tuple_elements(result, tupl, std::index_sequence_for<T...>{});
367 return result;
368 }
369
371
372 // TODO: ce_hash64(array/span)
373 // TODO: ce_hash64(thread::id) ?
374 // TODO: ce_hash64(optional/variant) ?
375
377}
constexpr auto to_u8(FROM byte) noexcept
Bit-casts the given bytelike to a uint8_t.
Definition bytes.h:80
constexpr uint64_t fnv64(RANGE &&bytes)
Calculates a FNV Hash for a range of bytes.
Definition hashes.h:171
constexpr uint64_t crc64(RANGE &&bytes)
Calculates a CRC4 for a range of bytelikes.
Definition hashes.h:136
constexpr uint64_t hash64(FIRST const &first, T &&... values)
Performs a hash of multiple values.
Definition hashes.h:274
constexpr void fold_in_hash64_range(uint64_t &seed, It first, It last, HASHER const &hasher={})
Combines an existing hash value (seed) with the hash of a range of values.
Definition hashes.h:297
constexpr void hash64_combine_to(uint64_t &seed, T &&v, HASHER &&hasher=HASHER{})
Combines an existing hash value (seed) with the hash of value v.
Definition hashes.h:265
constexpr void fold_in_hash64(uint64_t &hash1, uint64_t hash2) noexcept
Combines an existing hash with a new hash value.
Definition hashes.h:251
constexpr uint64_t hash64_range(It first, It last, HASHER &&hasher={})
Hashes a range of values.
Definition hashes.h:306
constexpr uint32_t crc32(RANGE &&bytes)
Calculates a CRC32 for a range of bytelikes.
Definition hashes.h:70
Hash functions that only work on integers.
Definition hashes.h:190
Primary namespace for everything in this library.
Definition align+rec2.h:10