1 //===----------------------------------------------------------------------===// 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 #ifndef _LIBCPP___FUNCTIONAL_HASH_H 10 #define _LIBCPP___FUNCTIONAL_HASH_H 11 12 #include <__config> 13 #include <__functional/unary_function.h> 14 #include <__tuple> 15 #include <__utility/forward.h> 16 #include <__utility/move.h> 17 #include <__utility/pair.h> 18 #include <__utility/swap.h> 19 #include <cstdint> 20 #include <cstring> 21 #include <cstddef> 22 #include <limits> 23 #include <type_traits> 24 25 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 26 #pragma GCC system_header 27 #endif 28 29 _LIBCPP_PUSH_MACROS 30 #include <__undef_macros> 31 32 _LIBCPP_BEGIN_NAMESPACE_STD 33 34 template <class _Size> 35 inline _LIBCPP_INLINE_VISIBILITY 36 _Size 37 __loadword(const void* __p) 38 { 39 _Size __r; 40 _VSTD::memcpy(&__r, __p, sizeof(__r)); 41 return __r; 42 } 43 44 // We use murmur2 when size_t is 32 bits, and cityhash64 when size_t 45 // is 64 bits. This is because cityhash64 uses 64bit x 64bit 46 // multiplication, which can be very slow on 32-bit systems. 47 template <class _Size, size_t = sizeof(_Size)*__CHAR_BIT__> 48 struct __murmur2_or_cityhash; 49 50 template <class _Size> 51 struct __murmur2_or_cityhash<_Size, 32> 52 { 53 inline _Size operator()(const void* __key, _Size __len) 54 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK; 55 }; 56 57 // murmur2 58 template <class _Size> 59 _Size 60 __murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len) 61 { 62 const _Size __m = 0x5bd1e995; 63 const _Size __r = 24; 64 _Size __h = __len; 65 const unsigned char* __data = static_cast<const unsigned char*>(__key); 66 for (; __len >= 4; __data += 4, __len -= 4) 67 { 68 _Size __k = __loadword<_Size>(__data); 69 __k *= __m; 70 __k ^= __k >> __r; 71 __k *= __m; 72 __h *= __m; 73 __h ^= __k; 74 } 75 switch (__len) 76 { 77 case 3: 78 __h ^= static_cast<_Size>(__data[2] << 16); 79 _LIBCPP_FALLTHROUGH(); 80 case 2: 81 __h ^= static_cast<_Size>(__data[1] << 8); 82 _LIBCPP_FALLTHROUGH(); 83 case 1: 84 __h ^= __data[0]; 85 __h *= __m; 86 } 87 __h ^= __h >> 13; 88 __h *= __m; 89 __h ^= __h >> 15; 90 return __h; 91 } 92 93 template <class _Size> 94 struct __murmur2_or_cityhash<_Size, 64> 95 { 96 inline _Size operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK; 97 98 private: 99 // Some primes between 2^63 and 2^64. 100 static const _Size __k0 = 0xc3a5c85c97cb3127ULL; 101 static const _Size __k1 = 0xb492b66fbe98f273ULL; 102 static const _Size __k2 = 0x9ae16a3b2f90404fULL; 103 static const _Size __k3 = 0xc949d7c7509e6557ULL; 104 105 static _Size __rotate(_Size __val, int __shift) { 106 return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift))); 107 } 108 109 static _Size __rotate_by_at_least_1(_Size __val, int __shift) { 110 return (__val >> __shift) | (__val << (64 - __shift)); 111 } 112 113 static _Size __shift_mix(_Size __val) { 114 return __val ^ (__val >> 47); 115 } 116 117 static _Size __hash_len_16(_Size __u, _Size __v) 118 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 119 { 120 const _Size __mul = 0x9ddfea08eb382d69ULL; 121 _Size __a = (__u ^ __v) * __mul; 122 __a ^= (__a >> 47); 123 _Size __b = (__v ^ __a) * __mul; 124 __b ^= (__b >> 47); 125 __b *= __mul; 126 return __b; 127 } 128 129 static _Size __hash_len_0_to_16(const char* __s, _Size __len) 130 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 131 { 132 if (__len > 8) { 133 const _Size __a = __loadword<_Size>(__s); 134 const _Size __b = __loadword<_Size>(__s + __len - 8); 135 return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b; 136 } 137 if (__len >= 4) { 138 const uint32_t __a = __loadword<uint32_t>(__s); 139 const uint32_t __b = __loadword<uint32_t>(__s + __len - 4); 140 return __hash_len_16(__len + (__a << 3), __b); 141 } 142 if (__len > 0) { 143 const unsigned char __a = static_cast<unsigned char>(__s[0]); 144 const unsigned char __b = static_cast<unsigned char>(__s[__len >> 1]); 145 const unsigned char __c = static_cast<unsigned char>(__s[__len - 1]); 146 const uint32_t __y = static_cast<uint32_t>(__a) + 147 (static_cast<uint32_t>(__b) << 8); 148 const uint32_t __z = __len + (static_cast<uint32_t>(__c) << 2); 149 return __shift_mix(__y * __k2 ^ __z * __k3) * __k2; 150 } 151 return __k2; 152 } 153 154 static _Size __hash_len_17_to_32(const char *__s, _Size __len) 155 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 156 { 157 const _Size __a = __loadword<_Size>(__s) * __k1; 158 const _Size __b = __loadword<_Size>(__s + 8); 159 const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2; 160 const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0; 161 return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d, 162 __a + __rotate(__b ^ __k3, 20) - __c + __len); 163 } 164 165 // Return a 16-byte hash for 48 bytes. Quick and dirty. 166 // Callers do best to use "random-looking" values for a and b. 167 static pair<_Size, _Size> __weak_hash_len_32_with_seeds( 168 _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) 169 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 170 { 171 __a += __w; 172 __b = __rotate(__b + __a + __z, 21); 173 const _Size __c = __a; 174 __a += __x; 175 __a += __y; 176 __b += __rotate(__a, 44); 177 return pair<_Size, _Size>(__a + __z, __b + __c); 178 } 179 180 // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. 181 static pair<_Size, _Size> __weak_hash_len_32_with_seeds( 182 const char* __s, _Size __a, _Size __b) 183 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 184 { 185 return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s), 186 __loadword<_Size>(__s + 8), 187 __loadword<_Size>(__s + 16), 188 __loadword<_Size>(__s + 24), 189 __a, 190 __b); 191 } 192 193 // Return an 8-byte hash for 33 to 64 bytes. 194 static _Size __hash_len_33_to_64(const char *__s, size_t __len) 195 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 196 { 197 _Size __z = __loadword<_Size>(__s + 24); 198 _Size __a = __loadword<_Size>(__s) + 199 (__len + __loadword<_Size>(__s + __len - 16)) * __k0; 200 _Size __b = __rotate(__a + __z, 52); 201 _Size __c = __rotate(__a, 37); 202 __a += __loadword<_Size>(__s + 8); 203 __c += __rotate(__a, 7); 204 __a += __loadword<_Size>(__s + 16); 205 _Size __vf = __a + __z; 206 _Size __vs = __b + __rotate(__a, 31) + __c; 207 __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32); 208 __z += __loadword<_Size>(__s + __len - 8); 209 __b = __rotate(__a + __z, 52); 210 __c = __rotate(__a, 37); 211 __a += __loadword<_Size>(__s + __len - 24); 212 __c += __rotate(__a, 7); 213 __a += __loadword<_Size>(__s + __len - 16); 214 _Size __wf = __a + __z; 215 _Size __ws = __b + __rotate(__a, 31) + __c; 216 _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); 217 return __shift_mix(__r * __k0 + __vs) * __k2; 218 } 219 }; 220 221 // cityhash64 222 template <class _Size> 223 _Size 224 __murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len) 225 { 226 const char* __s = static_cast<const char*>(__key); 227 if (__len <= 32) { 228 if (__len <= 16) { 229 return __hash_len_0_to_16(__s, __len); 230 } else { 231 return __hash_len_17_to_32(__s, __len); 232 } 233 } else if (__len <= 64) { 234 return __hash_len_33_to_64(__s, __len); 235 } 236 237 // For strings over 64 bytes we hash the end first, and then as we 238 // loop we keep 56 bytes of state: v, w, x, y, and z. 239 _Size __x = __loadword<_Size>(__s + __len - 40); 240 _Size __y = __loadword<_Size>(__s + __len - 16) + 241 __loadword<_Size>(__s + __len - 56); 242 _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len, 243 __loadword<_Size>(__s + __len - 24)); 244 pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); 245 pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); 246 __x = __x * __k1 + __loadword<_Size>(__s); 247 248 // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. 249 __len = (__len - 1) & ~static_cast<_Size>(63); 250 do { 251 __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1; 252 __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1; 253 __x ^= __w.second; 254 __y += __v.first + __loadword<_Size>(__s + 40); 255 __z = __rotate(__z + __w.first, 33) * __k1; 256 __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); 257 __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, 258 __y + __loadword<_Size>(__s + 16)); 259 _VSTD::swap(__z, __x); 260 __s += 64; 261 __len -= 64; 262 } while (__len != 0); 263 return __hash_len_16( 264 __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, 265 __hash_len_16(__v.second, __w.second) + __x); 266 } 267 268 template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)> 269 struct __scalar_hash; 270 271 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 272 template <class _Tp> 273 struct __scalar_hash<_Tp, 0> 274 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 275 : public unary_function<_Tp, size_t> 276 #endif 277 { 278 _LIBCPP_SUPPRESS_DEPRECATED_POP 279 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 280 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 281 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; 282 #endif 283 _LIBCPP_INLINE_VISIBILITY 284 size_t operator()(_Tp __v) const _NOEXCEPT 285 { 286 union 287 { 288 _Tp __t; 289 size_t __a; 290 } __u; 291 __u.__a = 0; 292 __u.__t = __v; 293 return __u.__a; 294 } 295 }; 296 297 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 298 template <class _Tp> 299 struct __scalar_hash<_Tp, 1> 300 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 301 : public unary_function<_Tp, size_t> 302 #endif 303 { 304 _LIBCPP_SUPPRESS_DEPRECATED_POP 305 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 306 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 307 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; 308 #endif 309 _LIBCPP_INLINE_VISIBILITY 310 size_t operator()(_Tp __v) const _NOEXCEPT 311 { 312 union 313 { 314 _Tp __t; 315 size_t __a; 316 } __u; 317 __u.__t = __v; 318 return __u.__a; 319 } 320 }; 321 322 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 323 template <class _Tp> 324 struct __scalar_hash<_Tp, 2> 325 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 326 : public unary_function<_Tp, size_t> 327 #endif 328 { 329 _LIBCPP_SUPPRESS_DEPRECATED_POP 330 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 331 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 332 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; 333 #endif 334 _LIBCPP_INLINE_VISIBILITY 335 size_t operator()(_Tp __v) const _NOEXCEPT 336 { 337 union 338 { 339 _Tp __t; 340 struct 341 { 342 size_t __a; 343 size_t __b; 344 } __s; 345 } __u; 346 __u.__t = __v; 347 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u)); 348 } 349 }; 350 351 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 352 template <class _Tp> 353 struct __scalar_hash<_Tp, 3> 354 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 355 : public unary_function<_Tp, size_t> 356 #endif 357 { 358 _LIBCPP_SUPPRESS_DEPRECATED_POP 359 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 360 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 361 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; 362 #endif 363 _LIBCPP_INLINE_VISIBILITY 364 size_t operator()(_Tp __v) const _NOEXCEPT 365 { 366 union 367 { 368 _Tp __t; 369 struct 370 { 371 size_t __a; 372 size_t __b; 373 size_t __c; 374 } __s; 375 } __u; 376 __u.__t = __v; 377 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u)); 378 } 379 }; 380 381 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 382 template <class _Tp> 383 struct __scalar_hash<_Tp, 4> 384 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 385 : public unary_function<_Tp, size_t> 386 #endif 387 { 388 _LIBCPP_SUPPRESS_DEPRECATED_POP 389 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 390 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 391 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; 392 #endif 393 _LIBCPP_INLINE_VISIBILITY 394 size_t operator()(_Tp __v) const _NOEXCEPT 395 { 396 union 397 { 398 _Tp __t; 399 struct 400 { 401 size_t __a; 402 size_t __b; 403 size_t __c; 404 size_t __d; 405 } __s; 406 } __u; 407 __u.__t = __v; 408 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u)); 409 } 410 }; 411 412 struct _PairT { 413 size_t first; 414 size_t second; 415 }; 416 417 _LIBCPP_INLINE_VISIBILITY 418 inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { 419 typedef __scalar_hash<_PairT> _HashT; 420 const _PairT __p = {__lhs, __rhs}; 421 return _HashT()(__p); 422 } 423 424 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 425 template<class _Tp> 426 struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> 427 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 428 : public unary_function<_Tp*, size_t> 429 #endif 430 { 431 _LIBCPP_SUPPRESS_DEPRECATED_POP 432 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 433 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 434 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* argument_type; 435 #endif 436 _LIBCPP_INLINE_VISIBILITY 437 size_t operator()(_Tp* __v) const _NOEXCEPT 438 { 439 union 440 { 441 _Tp* __t; 442 size_t __a; 443 } __u; 444 __u.__t = __v; 445 return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u)); 446 } 447 }; 448 449 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 450 template <> 451 struct _LIBCPP_TEMPLATE_VIS hash<bool> 452 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 453 : public unary_function<bool, size_t> 454 #endif 455 { 456 _LIBCPP_SUPPRESS_DEPRECATED_POP 457 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 458 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 459 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool argument_type; 460 #endif 461 _LIBCPP_INLINE_VISIBILITY 462 size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 463 }; 464 465 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 466 template <> 467 struct _LIBCPP_TEMPLATE_VIS hash<char> 468 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 469 : public unary_function<char, size_t> 470 #endif 471 { 472 _LIBCPP_SUPPRESS_DEPRECATED_POP 473 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 474 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 475 _LIBCPP_DEPRECATED_IN_CXX17 typedef char argument_type; 476 #endif 477 _LIBCPP_INLINE_VISIBILITY 478 size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 479 }; 480 481 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 482 template <> 483 struct _LIBCPP_TEMPLATE_VIS hash<signed char> 484 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 485 : public unary_function<signed char, size_t> 486 #endif 487 { 488 _LIBCPP_SUPPRESS_DEPRECATED_POP 489 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 490 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 491 _LIBCPP_DEPRECATED_IN_CXX17 typedef signed char argument_type; 492 #endif 493 _LIBCPP_INLINE_VISIBILITY 494 size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 495 }; 496 497 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 498 template <> 499 struct _LIBCPP_TEMPLATE_VIS hash<unsigned char> 500 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 501 : public unary_function<unsigned char, size_t> 502 #endif 503 { 504 _LIBCPP_SUPPRESS_DEPRECATED_POP 505 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 506 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 507 _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned char argument_type; 508 #endif 509 _LIBCPP_INLINE_VISIBILITY 510 size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 511 }; 512 513 #ifndef _LIBCPP_HAS_NO_CHAR8_T 514 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 515 template <> 516 struct _LIBCPP_TEMPLATE_VIS hash<char8_t> 517 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 518 : public unary_function<char8_t, size_t> 519 #endif 520 { 521 _LIBCPP_SUPPRESS_DEPRECATED_POP 522 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 523 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 524 _LIBCPP_DEPRECATED_IN_CXX17 typedef char8_t argument_type; 525 #endif 526 _LIBCPP_INLINE_VISIBILITY 527 size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 528 }; 529 #endif // !_LIBCPP_HAS_NO_CHAR8_T 530 531 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS 532 533 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 534 template <> 535 struct _LIBCPP_TEMPLATE_VIS hash<char16_t> 536 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 537 : public unary_function<char16_t, size_t> 538 #endif 539 { 540 _LIBCPP_SUPPRESS_DEPRECATED_POP 541 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 542 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 543 _LIBCPP_DEPRECATED_IN_CXX17 typedef char16_t argument_type; 544 #endif 545 _LIBCPP_INLINE_VISIBILITY 546 size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 547 }; 548 549 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 550 template <> 551 struct _LIBCPP_TEMPLATE_VIS hash<char32_t> 552 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 553 : public unary_function<char32_t, size_t> 554 #endif 555 { 556 _LIBCPP_SUPPRESS_DEPRECATED_POP 557 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 558 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 559 _LIBCPP_DEPRECATED_IN_CXX17 typedef char32_t argument_type; 560 #endif 561 _LIBCPP_INLINE_VISIBILITY 562 size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 563 }; 564 565 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS 566 567 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 568 template <> 569 struct _LIBCPP_TEMPLATE_VIS hash<wchar_t> 570 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 571 : public unary_function<wchar_t, size_t> 572 #endif 573 { 574 _LIBCPP_SUPPRESS_DEPRECATED_POP 575 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 576 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 577 _LIBCPP_DEPRECATED_IN_CXX17 typedef wchar_t argument_type; 578 #endif 579 _LIBCPP_INLINE_VISIBILITY 580 size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 581 }; 582 583 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 584 template <> 585 struct _LIBCPP_TEMPLATE_VIS hash<short> 586 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 587 : public unary_function<short, size_t> 588 #endif 589 { 590 _LIBCPP_SUPPRESS_DEPRECATED_POP 591 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 592 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 593 _LIBCPP_DEPRECATED_IN_CXX17 typedef short argument_type; 594 #endif 595 _LIBCPP_INLINE_VISIBILITY 596 size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 597 }; 598 599 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 600 template <> 601 struct _LIBCPP_TEMPLATE_VIS hash<unsigned short> 602 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 603 : public unary_function<unsigned short, size_t> 604 #endif 605 { 606 _LIBCPP_SUPPRESS_DEPRECATED_POP 607 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 608 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 609 _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned short argument_type; 610 #endif 611 _LIBCPP_INLINE_VISIBILITY 612 size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 613 }; 614 615 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 616 template <> 617 struct _LIBCPP_TEMPLATE_VIS hash<int> 618 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 619 : public unary_function<int, size_t> 620 #endif 621 { 622 _LIBCPP_SUPPRESS_DEPRECATED_POP 623 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 624 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 625 _LIBCPP_DEPRECATED_IN_CXX17 typedef int argument_type; 626 #endif 627 _LIBCPP_INLINE_VISIBILITY 628 size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 629 }; 630 631 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 632 template <> 633 struct _LIBCPP_TEMPLATE_VIS hash<unsigned int> 634 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 635 : public unary_function<unsigned int, size_t> 636 #endif 637 { 638 _LIBCPP_SUPPRESS_DEPRECATED_POP 639 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 640 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 641 _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned int argument_type; 642 #endif 643 _LIBCPP_INLINE_VISIBILITY 644 size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 645 }; 646 647 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 648 template <> 649 struct _LIBCPP_TEMPLATE_VIS hash<long> 650 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 651 : public unary_function<long, size_t> 652 #endif 653 { 654 _LIBCPP_SUPPRESS_DEPRECATED_POP 655 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 656 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 657 _LIBCPP_DEPRECATED_IN_CXX17 typedef long argument_type; 658 #endif 659 _LIBCPP_INLINE_VISIBILITY 660 size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 661 }; 662 663 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 664 template <> 665 struct _LIBCPP_TEMPLATE_VIS hash<unsigned long> 666 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 667 : public unary_function<unsigned long, size_t> 668 #endif 669 { 670 _LIBCPP_SUPPRESS_DEPRECATED_POP 671 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 672 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 673 _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned long argument_type; 674 #endif 675 _LIBCPP_INLINE_VISIBILITY 676 size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);} 677 }; 678 679 template <> 680 struct _LIBCPP_TEMPLATE_VIS hash<long long> 681 : public __scalar_hash<long long> 682 { 683 }; 684 685 template <> 686 struct _LIBCPP_TEMPLATE_VIS hash<unsigned long long> 687 : public __scalar_hash<unsigned long long> 688 { 689 }; 690 691 #ifndef _LIBCPP_HAS_NO_INT128 692 693 template <> 694 struct _LIBCPP_TEMPLATE_VIS hash<__int128_t> 695 : public __scalar_hash<__int128_t> 696 { 697 }; 698 699 template <> 700 struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t> 701 : public __scalar_hash<__uint128_t> 702 { 703 }; 704 705 #endif 706 707 template <> 708 struct _LIBCPP_TEMPLATE_VIS hash<float> 709 : public __scalar_hash<float> 710 { 711 _LIBCPP_INLINE_VISIBILITY 712 size_t operator()(float __v) const _NOEXCEPT 713 { 714 // -0.0 and 0.0 should return same hash 715 if (__v == 0.0f) 716 return 0; 717 return __scalar_hash<float>::operator()(__v); 718 } 719 }; 720 721 template <> 722 struct _LIBCPP_TEMPLATE_VIS hash<double> 723 : public __scalar_hash<double> 724 { 725 _LIBCPP_INLINE_VISIBILITY 726 size_t operator()(double __v) const _NOEXCEPT 727 { 728 // -0.0 and 0.0 should return same hash 729 if (__v == 0.0) 730 return 0; 731 return __scalar_hash<double>::operator()(__v); 732 } 733 }; 734 735 template <> 736 struct _LIBCPP_TEMPLATE_VIS hash<long double> 737 : public __scalar_hash<long double> 738 { 739 _LIBCPP_INLINE_VISIBILITY 740 size_t operator()(long double __v) const _NOEXCEPT 741 { 742 // -0.0 and 0.0 should return same hash 743 if (__v == 0.0L) 744 return 0; 745 #if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__)) 746 // Zero out padding bits 747 union 748 { 749 long double __t; 750 struct 751 { 752 size_t __a; 753 size_t __b; 754 size_t __c; 755 size_t __d; 756 } __s; 757 } __u; 758 __u.__s.__a = 0; 759 __u.__s.__b = 0; 760 __u.__s.__c = 0; 761 __u.__s.__d = 0; 762 __u.__t = __v; 763 return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; 764 #elif defined(__x86_64__) 765 // Zero out padding bits 766 union 767 { 768 long double __t; 769 struct 770 { 771 size_t __a; 772 size_t __b; 773 } __s; 774 } __u; 775 __u.__s.__a = 0; 776 __u.__s.__b = 0; 777 __u.__t = __v; 778 return __u.__s.__a ^ __u.__s.__b; 779 #else 780 return __scalar_hash<long double>::operator()(__v); 781 #endif 782 } 783 }; 784 785 #if _LIBCPP_STD_VER > 11 786 787 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 788 template <class _Tp, bool = is_enum<_Tp>::value> 789 struct _LIBCPP_TEMPLATE_VIS __enum_hash 790 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 791 : public unary_function<_Tp, size_t> 792 #endif 793 { 794 _LIBCPP_SUPPRESS_DEPRECATED_POP 795 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 796 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 797 _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; 798 #endif 799 _LIBCPP_INLINE_VISIBILITY 800 size_t operator()(_Tp __v) const _NOEXCEPT 801 { 802 typedef typename underlying_type<_Tp>::type type; 803 return hash<type>{}(static_cast<type>(__v)); 804 } 805 }; 806 template <class _Tp> 807 struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> { 808 __enum_hash() = delete; 809 __enum_hash(__enum_hash const&) = delete; 810 __enum_hash& operator=(__enum_hash const&) = delete; 811 }; 812 813 template <class _Tp> 814 struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> 815 { 816 }; 817 #endif 818 819 #if _LIBCPP_STD_VER > 14 820 821 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 822 template <> 823 struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t> 824 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 825 : public unary_function<nullptr_t, size_t> 826 #endif 827 { 828 _LIBCPP_SUPPRESS_DEPRECATED_POP 829 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 830 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 831 _LIBCPP_DEPRECATED_IN_CXX17 typedef nullptr_t argument_type; 832 #endif 833 _LIBCPP_INLINE_VISIBILITY 834 size_t operator()(nullptr_t) const _NOEXCEPT { 835 return 662607004ull; 836 } 837 }; 838 #endif 839 840 #ifndef _LIBCPP_CXX03_LANG 841 template <class _Key, class _Hash> 842 using __check_hash_requirements _LIBCPP_NODEBUG_TYPE = integral_constant<bool, 843 is_copy_constructible<_Hash>::value && 844 is_move_constructible<_Hash>::value && 845 __invokable_r<size_t, _Hash, _Key const&>::value 846 >; 847 848 template <class _Key, class _Hash = hash<_Key> > 849 using __has_enabled_hash _LIBCPP_NODEBUG_TYPE = integral_constant<bool, 850 __check_hash_requirements<_Key, _Hash>::value && 851 is_default_constructible<_Hash>::value 852 >; 853 854 #if _LIBCPP_STD_VER > 14 855 template <class _Type, class> 856 using __enable_hash_helper_imp _LIBCPP_NODEBUG_TYPE = _Type; 857 858 template <class _Type, class ..._Keys> 859 using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = __enable_hash_helper_imp<_Type, 860 typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type 861 >; 862 #else 863 template <class _Type, class ...> 864 using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = _Type; 865 #endif 866 867 #endif // !_LIBCPP_CXX03_LANG 868 869 _LIBCPP_END_NAMESPACE_STD 870 871 _LIBCPP_POP_MACROS 872 873 #endif // _LIBCPP___FUNCTIONAL_HASH_H 874