1fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_HASH_H 10fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_HASH_H 11fe6060f1SDimitry Andric 12fe6060f1SDimitry Andric #include <__config> 13fe6060f1SDimitry Andric #include <__functional/unary_function.h> 14*0fca6ea1SDimitry Andric #include <__fwd/functional.h> 15*0fca6ea1SDimitry Andric #include <__type_traits/conjunction.h> 16*0fca6ea1SDimitry Andric #include <__type_traits/invoke.h> 17*0fca6ea1SDimitry Andric #include <__type_traits/is_constructible.h> 18bdd1243dSDimitry Andric #include <__type_traits/is_enum.h> 19bdd1243dSDimitry Andric #include <__type_traits/underlying_type.h> 20fe6060f1SDimitry Andric #include <__utility/pair.h> 21fe6060f1SDimitry Andric #include <__utility/swap.h> 2204eeddc0SDimitry Andric #include <cstddef> 23fe6060f1SDimitry Andric #include <cstdint> 24fe6060f1SDimitry Andric #include <cstring> 25fe6060f1SDimitry Andric 26fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 27fe6060f1SDimitry Andric # pragma GCC system_header 28fe6060f1SDimitry Andric #endif 29fe6060f1SDimitry Andric 30fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 31fe6060f1SDimitry Andric 32fe6060f1SDimitry Andric template <class _Size> 33cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _Size __loadword(const void* __p) { 34fe6060f1SDimitry Andric _Size __r; 355f757f3fSDimitry Andric std::memcpy(&__r, __p, sizeof(__r)); 36fe6060f1SDimitry Andric return __r; 37fe6060f1SDimitry Andric } 38fe6060f1SDimitry Andric 39fe6060f1SDimitry Andric // We use murmur2 when size_t is 32 bits, and cityhash64 when size_t 40fe6060f1SDimitry Andric // is 64 bits. This is because cityhash64 uses 64bit x 64bit 41fe6060f1SDimitry Andric // multiplication, which can be very slow on 32-bit systems. 42fe6060f1SDimitry Andric template <class _Size, size_t = sizeof(_Size) * __CHAR_BIT__> 43fe6060f1SDimitry Andric struct __murmur2_or_cityhash; 44fe6060f1SDimitry Andric 45fe6060f1SDimitry Andric template <class _Size> 46cb14a3feSDimitry Andric struct __murmur2_or_cityhash<_Size, 32> { 47cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK _Size 48cb14a3feSDimitry Andric operator()(const void* __key, _Size __len) const { 49fe6060f1SDimitry Andric // murmur2 50fe6060f1SDimitry Andric const _Size __m = 0x5bd1e995; 51fe6060f1SDimitry Andric const _Size __r = 24; 52fe6060f1SDimitry Andric _Size __h = __len; 53fe6060f1SDimitry Andric const unsigned char* __data = static_cast<const unsigned char*>(__key); 54cb14a3feSDimitry Andric for (; __len >= 4; __data += 4, __len -= 4) { 55bdd1243dSDimitry Andric _Size __k = std::__loadword<_Size>(__data); 56fe6060f1SDimitry Andric __k *= __m; 57fe6060f1SDimitry Andric __k ^= __k >> __r; 58fe6060f1SDimitry Andric __k *= __m; 59fe6060f1SDimitry Andric __h *= __m; 60fe6060f1SDimitry Andric __h ^= __k; 61fe6060f1SDimitry Andric } 62cb14a3feSDimitry Andric switch (__len) { 63fe6060f1SDimitry Andric case 3: 64fe6060f1SDimitry Andric __h ^= static_cast<_Size>(__data[2] << 16); 65fe6060f1SDimitry Andric _LIBCPP_FALLTHROUGH(); 66fe6060f1SDimitry Andric case 2: 67fe6060f1SDimitry Andric __h ^= static_cast<_Size>(__data[1] << 8); 68fe6060f1SDimitry Andric _LIBCPP_FALLTHROUGH(); 69fe6060f1SDimitry Andric case 1: 70fe6060f1SDimitry Andric __h ^= __data[0]; 71fe6060f1SDimitry Andric __h *= __m; 72fe6060f1SDimitry Andric } 73fe6060f1SDimitry Andric __h ^= __h >> 13; 74fe6060f1SDimitry Andric __h *= __m; 75fe6060f1SDimitry Andric __h ^= __h >> 15; 76fe6060f1SDimitry Andric return __h; 77fe6060f1SDimitry Andric } 7806c3fb27SDimitry Andric }; 79fe6060f1SDimitry Andric 80fe6060f1SDimitry Andric template <class _Size> 81cb14a3feSDimitry Andric struct __murmur2_or_cityhash<_Size, 64> { 82fe6060f1SDimitry Andric // cityhash64 83cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK _Size 84cb14a3feSDimitry Andric operator()(const void* __key, _Size __len) const { 85fe6060f1SDimitry Andric const char* __s = static_cast<const char*>(__key); 86fe6060f1SDimitry Andric if (__len <= 32) { 87fe6060f1SDimitry Andric if (__len <= 16) { 88fe6060f1SDimitry Andric return __hash_len_0_to_16(__s, __len); 89fe6060f1SDimitry Andric } else { 90fe6060f1SDimitry Andric return __hash_len_17_to_32(__s, __len); 91fe6060f1SDimitry Andric } 92fe6060f1SDimitry Andric } else if (__len <= 64) { 93fe6060f1SDimitry Andric return __hash_len_33_to_64(__s, __len); 94fe6060f1SDimitry Andric } 95fe6060f1SDimitry Andric 96fe6060f1SDimitry Andric // For strings over 64 bytes we hash the end first, and then as we 97fe6060f1SDimitry Andric // loop we keep 56 bytes of state: v, w, x, y, and z. 98bdd1243dSDimitry Andric _Size __x = std::__loadword<_Size>(__s + __len - 40); 99cb14a3feSDimitry Andric _Size __y = std::__loadword<_Size>(__s + __len - 16) + std::__loadword<_Size>(__s + __len - 56); 100cb14a3feSDimitry Andric _Size __z = 101cb14a3feSDimitry Andric __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, std::__loadword<_Size>(__s + __len - 24)); 102fe6060f1SDimitry Andric pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); 103fe6060f1SDimitry Andric pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); 104bdd1243dSDimitry Andric __x = __x * __k1 + std::__loadword<_Size>(__s); 105fe6060f1SDimitry Andric 106fe6060f1SDimitry Andric // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. 107fe6060f1SDimitry Andric __len = (__len - 1) & ~static_cast<_Size>(63); 108fe6060f1SDimitry Andric do { 109bdd1243dSDimitry Andric __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; 110bdd1243dSDimitry Andric __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; 111fe6060f1SDimitry Andric __x ^= __w.second; 112bdd1243dSDimitry Andric __y += __v.first + std::__loadword<_Size>(__s + 40); 113fe6060f1SDimitry Andric __z = __rotate(__z + __w.first, 33) * __k1; 114fe6060f1SDimitry Andric __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); 115cb14a3feSDimitry Andric __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, __y + std::__loadword<_Size>(__s + 16)); 1165f757f3fSDimitry Andric std::swap(__z, __x); 117fe6060f1SDimitry Andric __s += 64; 118fe6060f1SDimitry Andric __len -= 64; 119fe6060f1SDimitry Andric } while (__len != 0); 120cb14a3feSDimitry Andric return __hash_len_16(__hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, 121fe6060f1SDimitry Andric __hash_len_16(__v.second, __w.second) + __x); 122fe6060f1SDimitry Andric } 123fe6060f1SDimitry Andric 12406c3fb27SDimitry Andric private: 12506c3fb27SDimitry Andric // Some primes between 2^63 and 2^64. 12606c3fb27SDimitry Andric static const _Size __k0 = 0xc3a5c85c97cb3127ULL; 12706c3fb27SDimitry Andric static const _Size __k1 = 0xb492b66fbe98f273ULL; 12806c3fb27SDimitry Andric static const _Size __k2 = 0x9ae16a3b2f90404fULL; 12906c3fb27SDimitry Andric static const _Size __k3 = 0xc949d7c7509e6557ULL; 13006c3fb27SDimitry Andric 131cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Size __rotate(_Size __val, int __shift) { 13206c3fb27SDimitry Andric return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift))); 13306c3fb27SDimitry Andric } 13406c3fb27SDimitry Andric 135cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Size __rotate_by_at_least_1(_Size __val, int __shift) { 13606c3fb27SDimitry Andric return (__val >> __shift) | (__val << (64 - __shift)); 13706c3fb27SDimitry Andric } 13806c3fb27SDimitry Andric 139cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Size __shift_mix(_Size __val) { return __val ^ (__val >> 47); } 14006c3fb27SDimitry Andric 141cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size __hash_len_16(_Size __u, _Size __v) { 14206c3fb27SDimitry Andric const _Size __mul = 0x9ddfea08eb382d69ULL; 14306c3fb27SDimitry Andric _Size __a = (__u ^ __v) * __mul; 14406c3fb27SDimitry Andric __a ^= (__a >> 47); 14506c3fb27SDimitry Andric _Size __b = (__v ^ __a) * __mul; 14606c3fb27SDimitry Andric __b ^= (__b >> 47); 14706c3fb27SDimitry Andric __b *= __mul; 14806c3fb27SDimitry Andric return __b; 14906c3fb27SDimitry Andric } 15006c3fb27SDimitry Andric 151cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size 152cb14a3feSDimitry Andric __hash_len_0_to_16(const char* __s, _Size __len) { 15306c3fb27SDimitry Andric if (__len > 8) { 15406c3fb27SDimitry Andric const _Size __a = std::__loadword<_Size>(__s); 15506c3fb27SDimitry Andric const _Size __b = std::__loadword<_Size>(__s + __len - 8); 15606c3fb27SDimitry Andric return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b; 15706c3fb27SDimitry Andric } 15806c3fb27SDimitry Andric if (__len >= 4) { 15906c3fb27SDimitry Andric const uint32_t __a = std::__loadword<uint32_t>(__s); 16006c3fb27SDimitry Andric const uint32_t __b = std::__loadword<uint32_t>(__s + __len - 4); 16106c3fb27SDimitry Andric #ifdef _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION 16206c3fb27SDimitry Andric return __hash_len_16(__len + (static_cast<_Size>(__a) << 3), __b); 16306c3fb27SDimitry Andric #else 16406c3fb27SDimitry Andric return __hash_len_16(__len + (__a << 3), __b); 16506c3fb27SDimitry Andric #endif 16606c3fb27SDimitry Andric } 16706c3fb27SDimitry Andric if (__len > 0) { 16806c3fb27SDimitry Andric const unsigned char __a = static_cast<unsigned char>(__s[0]); 16906c3fb27SDimitry Andric const unsigned char __b = static_cast<unsigned char>(__s[__len >> 1]); 17006c3fb27SDimitry Andric const unsigned char __c = static_cast<unsigned char>(__s[__len - 1]); 171cb14a3feSDimitry Andric const uint32_t __y = static_cast<uint32_t>(__a) + (static_cast<uint32_t>(__b) << 8); 17206c3fb27SDimitry Andric const uint32_t __z = __len + (static_cast<uint32_t>(__c) << 2); 17306c3fb27SDimitry Andric return __shift_mix(__y * __k2 ^ __z * __k3) * __k2; 17406c3fb27SDimitry Andric } 17506c3fb27SDimitry Andric return __k2; 17606c3fb27SDimitry Andric } 17706c3fb27SDimitry Andric 178cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size 179cb14a3feSDimitry Andric __hash_len_17_to_32(const char* __s, _Size __len) { 18006c3fb27SDimitry Andric const _Size __a = std::__loadword<_Size>(__s) * __k1; 18106c3fb27SDimitry Andric const _Size __b = std::__loadword<_Size>(__s + 8); 18206c3fb27SDimitry Andric const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2; 18306c3fb27SDimitry Andric const _Size __d = std::__loadword<_Size>(__s + __len - 16) * __k0; 184cb14a3feSDimitry Andric return __hash_len_16( 185cb14a3feSDimitry Andric __rotate(__a - __b, 43) + __rotate(__c, 30) + __d, __a + __rotate(__b ^ __k3, 20) - __c + __len); 18606c3fb27SDimitry Andric } 18706c3fb27SDimitry Andric 18806c3fb27SDimitry Andric // Return a 16-byte hash for 48 bytes. Quick and dirty. 18906c3fb27SDimitry Andric // Callers do best to use "random-looking" values for a and b. 190cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static pair<_Size, _Size> 191cb14a3feSDimitry Andric __weak_hash_len_32_with_seeds(_Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) { 19206c3fb27SDimitry Andric __a += __w; 19306c3fb27SDimitry Andric __b = __rotate(__b + __a + __z, 21); 19406c3fb27SDimitry Andric const _Size __c = __a; 19506c3fb27SDimitry Andric __a += __x; 19606c3fb27SDimitry Andric __a += __y; 19706c3fb27SDimitry Andric __b += __rotate(__a, 44); 19806c3fb27SDimitry Andric return pair<_Size, _Size>(__a + __z, __b + __c); 19906c3fb27SDimitry Andric } 20006c3fb27SDimitry Andric 20106c3fb27SDimitry Andric // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. 202cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static pair<_Size, _Size> 203cb14a3feSDimitry Andric __weak_hash_len_32_with_seeds(const char* __s, _Size __a, _Size __b) { 204cb14a3feSDimitry Andric return __weak_hash_len_32_with_seeds( 205cb14a3feSDimitry Andric std::__loadword<_Size>(__s), 20606c3fb27SDimitry Andric std::__loadword<_Size>(__s + 8), 20706c3fb27SDimitry Andric std::__loadword<_Size>(__s + 16), 20806c3fb27SDimitry Andric std::__loadword<_Size>(__s + 24), 20906c3fb27SDimitry Andric __a, 21006c3fb27SDimitry Andric __b); 21106c3fb27SDimitry Andric } 21206c3fb27SDimitry Andric 21306c3fb27SDimitry Andric // Return an 8-byte hash for 33 to 64 bytes. 214cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size 215cb14a3feSDimitry Andric __hash_len_33_to_64(const char* __s, size_t __len) { 21606c3fb27SDimitry Andric _Size __z = std::__loadword<_Size>(__s + 24); 217cb14a3feSDimitry Andric _Size __a = std::__loadword<_Size>(__s) + (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0; 21806c3fb27SDimitry Andric _Size __b = __rotate(__a + __z, 52); 21906c3fb27SDimitry Andric _Size __c = __rotate(__a, 37); 22006c3fb27SDimitry Andric __a += std::__loadword<_Size>(__s + 8); 22106c3fb27SDimitry Andric __c += __rotate(__a, 7); 22206c3fb27SDimitry Andric __a += std::__loadword<_Size>(__s + 16); 22306c3fb27SDimitry Andric _Size __vf = __a + __z; 22406c3fb27SDimitry Andric _Size __vs = __b + __rotate(__a, 31) + __c; 22506c3fb27SDimitry Andric __a = std::__loadword<_Size>(__s + 16) + std::__loadword<_Size>(__s + __len - 32); 22606c3fb27SDimitry Andric __z += std::__loadword<_Size>(__s + __len - 8); 22706c3fb27SDimitry Andric __b = __rotate(__a + __z, 52); 22806c3fb27SDimitry Andric __c = __rotate(__a, 37); 22906c3fb27SDimitry Andric __a += std::__loadword<_Size>(__s + __len - 24); 23006c3fb27SDimitry Andric __c += __rotate(__a, 7); 23106c3fb27SDimitry Andric __a += std::__loadword<_Size>(__s + __len - 16); 23206c3fb27SDimitry Andric _Size __wf = __a + __z; 23306c3fb27SDimitry Andric _Size __ws = __b + __rotate(__a, 31) + __c; 23406c3fb27SDimitry Andric _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); 23506c3fb27SDimitry Andric return __shift_mix(__r * __k0 + __vs) * __k2; 23606c3fb27SDimitry Andric } 23706c3fb27SDimitry Andric }; 23806c3fb27SDimitry Andric 239fe6060f1SDimitry Andric template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)> 240fe6060f1SDimitry Andric struct __scalar_hash; 241fe6060f1SDimitry Andric 242fe6060f1SDimitry Andric template <class _Tp> 243cb14a3feSDimitry Andric struct __scalar_hash<_Tp, 0> : public __unary_function<_Tp, size_t> { 244cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { 245cb14a3feSDimitry Andric union { 246fe6060f1SDimitry Andric _Tp __t; 247fe6060f1SDimitry Andric size_t __a; 248fe6060f1SDimitry Andric } __u; 249fe6060f1SDimitry Andric __u.__a = 0; 250fe6060f1SDimitry Andric __u.__t = __v; 251fe6060f1SDimitry Andric return __u.__a; 252fe6060f1SDimitry Andric } 253fe6060f1SDimitry Andric }; 254fe6060f1SDimitry Andric 255fe6060f1SDimitry Andric template <class _Tp> 256cb14a3feSDimitry Andric struct __scalar_hash<_Tp, 1> : public __unary_function<_Tp, size_t> { 257cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { 258cb14a3feSDimitry Andric union { 259fe6060f1SDimitry Andric _Tp __t; 260fe6060f1SDimitry Andric size_t __a; 261fe6060f1SDimitry Andric } __u; 262fe6060f1SDimitry Andric __u.__t = __v; 263fe6060f1SDimitry Andric return __u.__a; 264fe6060f1SDimitry Andric } 265fe6060f1SDimitry Andric }; 266fe6060f1SDimitry Andric 267fe6060f1SDimitry Andric template <class _Tp> 268cb14a3feSDimitry Andric struct __scalar_hash<_Tp, 2> : public __unary_function<_Tp, size_t> { 269cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { 270cb14a3feSDimitry Andric union { 271fe6060f1SDimitry Andric _Tp __t; 272cb14a3feSDimitry Andric struct { 273fe6060f1SDimitry Andric size_t __a; 274fe6060f1SDimitry Andric size_t __b; 275fe6060f1SDimitry Andric } __s; 276fe6060f1SDimitry Andric } __u; 277fe6060f1SDimitry Andric __u.__t = __v; 278fe6060f1SDimitry Andric return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u)); 279fe6060f1SDimitry Andric } 280fe6060f1SDimitry Andric }; 281fe6060f1SDimitry Andric 282fe6060f1SDimitry Andric template <class _Tp> 283cb14a3feSDimitry Andric struct __scalar_hash<_Tp, 3> : public __unary_function<_Tp, size_t> { 284cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { 285cb14a3feSDimitry Andric union { 286fe6060f1SDimitry Andric _Tp __t; 287cb14a3feSDimitry Andric struct { 288fe6060f1SDimitry Andric size_t __a; 289fe6060f1SDimitry Andric size_t __b; 290fe6060f1SDimitry Andric size_t __c; 291fe6060f1SDimitry Andric } __s; 292fe6060f1SDimitry Andric } __u; 293fe6060f1SDimitry Andric __u.__t = __v; 294fe6060f1SDimitry Andric return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u)); 295fe6060f1SDimitry Andric } 296fe6060f1SDimitry Andric }; 297fe6060f1SDimitry Andric 298fe6060f1SDimitry Andric template <class _Tp> 299cb14a3feSDimitry Andric struct __scalar_hash<_Tp, 4> : public __unary_function<_Tp, size_t> { 300cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { 301cb14a3feSDimitry Andric union { 302fe6060f1SDimitry Andric _Tp __t; 303cb14a3feSDimitry Andric struct { 304fe6060f1SDimitry Andric size_t __a; 305fe6060f1SDimitry Andric size_t __b; 306fe6060f1SDimitry Andric size_t __c; 307fe6060f1SDimitry Andric size_t __d; 308fe6060f1SDimitry Andric } __s; 309fe6060f1SDimitry Andric } __u; 310fe6060f1SDimitry Andric __u.__t = __v; 311fe6060f1SDimitry Andric return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u)); 312fe6060f1SDimitry Andric } 313fe6060f1SDimitry Andric }; 314fe6060f1SDimitry Andric 315fe6060f1SDimitry Andric struct _PairT { 316fe6060f1SDimitry Andric size_t first; 317fe6060f1SDimitry Andric size_t second; 318fe6060f1SDimitry Andric }; 319fe6060f1SDimitry Andric 320cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { 321fe6060f1SDimitry Andric typedef __scalar_hash<_PairT> _HashT; 322fe6060f1SDimitry Andric const _PairT __p = {__lhs, __rhs}; 323fe6060f1SDimitry Andric return _HashT()(__p); 324fe6060f1SDimitry Andric } 325fe6060f1SDimitry Andric 326fe6060f1SDimitry Andric template <class _Tp> 327cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> : public __unary_function<_Tp*, size_t> { 328cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp* __v) const _NOEXCEPT { 329cb14a3feSDimitry Andric union { 330fe6060f1SDimitry Andric _Tp* __t; 331fe6060f1SDimitry Andric size_t __a; 332fe6060f1SDimitry Andric } __u; 333fe6060f1SDimitry Andric __u.__t = __v; 334fe6060f1SDimitry Andric return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u)); 335fe6060f1SDimitry Andric } 336fe6060f1SDimitry Andric }; 337fe6060f1SDimitry Andric 338fe6060f1SDimitry Andric template <> 339cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<bool> : public __unary_function<bool, size_t> { 340cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(bool __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 341fe6060f1SDimitry Andric }; 342fe6060f1SDimitry Andric 343fe6060f1SDimitry Andric template <> 344cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<char> : public __unary_function<char, size_t> { 345cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(char __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 346fe6060f1SDimitry Andric }; 347fe6060f1SDimitry Andric 348fe6060f1SDimitry Andric template <> 349cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<signed char> : public __unary_function<signed char, size_t> { 350cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(signed char __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 351fe6060f1SDimitry Andric }; 352fe6060f1SDimitry Andric 353fe6060f1SDimitry Andric template <> 354cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<unsigned char> : public __unary_function<unsigned char, size_t> { 355cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned char __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 356fe6060f1SDimitry Andric }; 357fe6060f1SDimitry Andric 358fe6060f1SDimitry Andric #ifndef _LIBCPP_HAS_NO_CHAR8_T 359fe6060f1SDimitry Andric template <> 360cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<char8_t> : public __unary_function<char8_t, size_t> { 361cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(char8_t __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 362fe6060f1SDimitry Andric }; 363fe6060f1SDimitry Andric #endif // !_LIBCPP_HAS_NO_CHAR8_T 364fe6060f1SDimitry Andric 365fe6060f1SDimitry Andric template <> 366cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<char16_t> : public __unary_function<char16_t, size_t> { 367cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(char16_t __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 368fe6060f1SDimitry Andric }; 369fe6060f1SDimitry Andric 370fe6060f1SDimitry Andric template <> 371cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<char32_t> : public __unary_function<char32_t, size_t> { 372cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(char32_t __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 373fe6060f1SDimitry Andric }; 374fe6060f1SDimitry Andric 375349cc55cSDimitry Andric #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 376fe6060f1SDimitry Andric template <> 377cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<wchar_t> : public __unary_function<wchar_t, size_t> { 378cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(wchar_t __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 379fe6060f1SDimitry Andric }; 380349cc55cSDimitry Andric #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 381fe6060f1SDimitry Andric 382fe6060f1SDimitry Andric template <> 383cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<short> : public __unary_function<short, size_t> { 384cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(short __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 385fe6060f1SDimitry Andric }; 386fe6060f1SDimitry Andric 387fe6060f1SDimitry Andric template <> 388cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<unsigned short> : public __unary_function<unsigned short, size_t> { 389cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned short __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 390fe6060f1SDimitry Andric }; 391fe6060f1SDimitry Andric 392fe6060f1SDimitry Andric template <> 393cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<int> : public __unary_function<int, size_t> { 394cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(int __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 395fe6060f1SDimitry Andric }; 396fe6060f1SDimitry Andric 397fe6060f1SDimitry Andric template <> 398cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<unsigned int> : public __unary_function<unsigned int, size_t> { 399cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned int __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 400fe6060f1SDimitry Andric }; 401fe6060f1SDimitry Andric 402fe6060f1SDimitry Andric template <> 403cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<long> : public __unary_function<long, size_t> { 404cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(long __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 405fe6060f1SDimitry Andric }; 406fe6060f1SDimitry Andric 407fe6060f1SDimitry Andric template <> 408cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<unsigned long> : public __unary_function<unsigned long, size_t> { 409cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned long __v) const _NOEXCEPT { return static_cast<size_t>(__v); } 410fe6060f1SDimitry Andric }; 411fe6060f1SDimitry Andric 412fe6060f1SDimitry Andric template <> 413cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<long long> : public __scalar_hash<long long> {}; 414fe6060f1SDimitry Andric 415fe6060f1SDimitry Andric template <> 416cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<unsigned long long> : public __scalar_hash<unsigned long long> {}; 417fe6060f1SDimitry Andric 418fe6060f1SDimitry Andric #ifndef _LIBCPP_HAS_NO_INT128 419fe6060f1SDimitry Andric 420fe6060f1SDimitry Andric template <> 421cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<__int128_t> : public __scalar_hash<__int128_t> {}; 422fe6060f1SDimitry Andric 423fe6060f1SDimitry Andric template <> 424cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t> : public __scalar_hash<__uint128_t> {}; 425fe6060f1SDimitry Andric 426fe6060f1SDimitry Andric #endif 427fe6060f1SDimitry Andric 428fe6060f1SDimitry Andric template <> 429cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<float> : public __scalar_hash<float> { 430cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(float __v) const _NOEXCEPT { 431fe6060f1SDimitry Andric // -0.0 and 0.0 should return same hash 432fe6060f1SDimitry Andric if (__v == 0.0f) 433fe6060f1SDimitry Andric return 0; 434fe6060f1SDimitry Andric return __scalar_hash<float>::operator()(__v); 435fe6060f1SDimitry Andric } 436fe6060f1SDimitry Andric }; 437fe6060f1SDimitry Andric 438fe6060f1SDimitry Andric template <> 439cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<double> : public __scalar_hash<double> { 440cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(double __v) const _NOEXCEPT { 441fe6060f1SDimitry Andric // -0.0 and 0.0 should return same hash 442fe6060f1SDimitry Andric if (__v == 0.0) 443fe6060f1SDimitry Andric return 0; 444fe6060f1SDimitry Andric return __scalar_hash<double>::operator()(__v); 445fe6060f1SDimitry Andric } 446fe6060f1SDimitry Andric }; 447fe6060f1SDimitry Andric 448fe6060f1SDimitry Andric template <> 449cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<long double> : public __scalar_hash<long double> { 450cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(long double __v) const _NOEXCEPT { 451fe6060f1SDimitry Andric // -0.0 and 0.0 should return same hash 452fe6060f1SDimitry Andric if (__v == 0.0L) 453fe6060f1SDimitry Andric return 0; 454fe6060f1SDimitry Andric #if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__)) 455fe6060f1SDimitry Andric // Zero out padding bits 456cb14a3feSDimitry Andric union { 457fe6060f1SDimitry Andric long double __t; 458cb14a3feSDimitry Andric struct { 459fe6060f1SDimitry Andric size_t __a; 460fe6060f1SDimitry Andric size_t __b; 461fe6060f1SDimitry Andric size_t __c; 462fe6060f1SDimitry Andric size_t __d; 463fe6060f1SDimitry Andric } __s; 464fe6060f1SDimitry Andric } __u; 465fe6060f1SDimitry Andric __u.__s.__a = 0; 466fe6060f1SDimitry Andric __u.__s.__b = 0; 467fe6060f1SDimitry Andric __u.__s.__c = 0; 468fe6060f1SDimitry Andric __u.__s.__d = 0; 469fe6060f1SDimitry Andric __u.__t = __v; 470fe6060f1SDimitry Andric return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; 471fe6060f1SDimitry Andric #elif defined(__x86_64__) 472fe6060f1SDimitry Andric // Zero out padding bits 473cb14a3feSDimitry Andric union { 474fe6060f1SDimitry Andric long double __t; 475cb14a3feSDimitry Andric struct { 476fe6060f1SDimitry Andric size_t __a; 477fe6060f1SDimitry Andric size_t __b; 478fe6060f1SDimitry Andric } __s; 479fe6060f1SDimitry Andric } __u; 480fe6060f1SDimitry Andric __u.__s.__a = 0; 481fe6060f1SDimitry Andric __u.__s.__b = 0; 482fe6060f1SDimitry Andric __u.__t = __v; 483fe6060f1SDimitry Andric return __u.__s.__a ^ __u.__s.__b; 484fe6060f1SDimitry Andric #else 485fe6060f1SDimitry Andric return __scalar_hash<long double>::operator()(__v); 486fe6060f1SDimitry Andric #endif 487fe6060f1SDimitry Andric } 488fe6060f1SDimitry Andric }; 489fe6060f1SDimitry Andric 490fe6060f1SDimitry Andric template <class _Tp, bool = is_enum<_Tp>::value> 491cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS __enum_hash : public __unary_function<_Tp, size_t> { 492cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { 493fe6060f1SDimitry Andric typedef typename underlying_type<_Tp>::type type; 49481ad6265SDimitry Andric return hash<type>()(static_cast<type>(__v)); 495fe6060f1SDimitry Andric } 496fe6060f1SDimitry Andric }; 497fe6060f1SDimitry Andric template <class _Tp> 498fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> { 499fe6060f1SDimitry Andric __enum_hash() = delete; 500fe6060f1SDimitry Andric __enum_hash(__enum_hash const&) = delete; 501fe6060f1SDimitry Andric __enum_hash& operator=(__enum_hash const&) = delete; 502fe6060f1SDimitry Andric }; 503fe6060f1SDimitry Andric 504fe6060f1SDimitry Andric template <class _Tp> 505cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> {}; 506fe6060f1SDimitry Andric 50706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17 508fe6060f1SDimitry Andric 509fe6060f1SDimitry Andric template <> 510cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t> : public __unary_function<nullptr_t, size_t> { 511cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; } 512fe6060f1SDimitry Andric }; 513fe6060f1SDimitry Andric #endif 514fe6060f1SDimitry Andric 515fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 516fe6060f1SDimitry Andric template <class _Key, class _Hash> 517cb14a3feSDimitry Andric using __check_hash_requirements _LIBCPP_NODEBUG = 518cb14a3feSDimitry Andric integral_constant<bool, 519cb14a3feSDimitry Andric is_copy_constructible<_Hash>::value && is_move_constructible<_Hash>::value && 520cb14a3feSDimitry Andric __invokable_r<size_t, _Hash, _Key const&>::value >; 521fe6060f1SDimitry Andric 522fe6060f1SDimitry Andric template <class _Key, class _Hash = hash<_Key> > 523cb14a3feSDimitry Andric using __has_enabled_hash _LIBCPP_NODEBUG = 524cb14a3feSDimitry Andric integral_constant<bool, __check_hash_requirements<_Key, _Hash>::value && is_default_constructible<_Hash>::value >; 525fe6060f1SDimitry Andric 52606c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 17 527fe6060f1SDimitry Andric template <class _Type, class> 528349cc55cSDimitry Andric using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type; 529fe6060f1SDimitry Andric 530fe6060f1SDimitry Andric template <class _Type, class... _Keys> 531cb14a3feSDimitry Andric using __enable_hash_helper _LIBCPP_NODEBUG = 532cb14a3feSDimitry Andric __enable_hash_helper_imp<_Type, __enable_if_t<__all<__has_enabled_hash<_Keys>::value...>::value> >; 533fe6060f1SDimitry Andric # else 534fe6060f1SDimitry Andric template <class _Type, class...> 535349cc55cSDimitry Andric using __enable_hash_helper _LIBCPP_NODEBUG = _Type; 536fe6060f1SDimitry Andric # endif 537fe6060f1SDimitry Andric 538fe6060f1SDimitry Andric #endif // !_LIBCPP_CXX03_LANG 539fe6060f1SDimitry Andric 540fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 541fe6060f1SDimitry Andric 542fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_HASH_H 543