zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob dfd8ea25 (19990B) - Raw


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