|
19 | 19 | #include <__type_traits/invoke.h> |
20 | 20 | #include <__type_traits/is_constructible.h> |
21 | 21 | #include <__type_traits/is_enum.h> |
| 22 | +#include <__type_traits/is_floating_point.h> |
| 23 | +#include <__type_traits/is_integral.h> |
22 | 24 | #include <__type_traits/underlying_type.h> |
23 | 25 | #include <__utility/pair.h> |
24 | 26 | #include <__utility/swap.h> |
@@ -345,122 +347,43 @@ struct hash<_Tp*> : public __unary_function<_Tp*, size_t> { |
345 | 347 | } |
346 | 348 | }; |
347 | 349 |
|
348 | | -template <> |
349 | | -struct hash<bool> : public __unary_function<bool, size_t> { |
350 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(bool __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
351 | | -}; |
352 | | - |
353 | | -template <> |
354 | | -struct hash<char> : public __unary_function<char, size_t> { |
355 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(char __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
356 | | -}; |
357 | | - |
358 | | -template <> |
359 | | -struct hash<signed char> : public __unary_function<signed char, size_t> { |
360 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(signed char __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
361 | | -}; |
362 | | - |
363 | | -template <> |
364 | | -struct hash<unsigned char> : public __unary_function<unsigned char, size_t> { |
365 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned char __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
| 350 | +template <class _Tp, class = void> |
| 351 | +struct __hash_impl { |
| 352 | + __hash_impl() = delete; |
| 353 | + __hash_impl(__hash_impl const&) = delete; |
| 354 | + __hash_impl& operator=(__hash_impl const&) = delete; |
366 | 355 | }; |
367 | 356 |
|
368 | | -#if _LIBCPP_HAS_CHAR8_T |
369 | | -template <> |
370 | | -struct hash<char8_t> : public __unary_function<char8_t, size_t> { |
371 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(char8_t __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
372 | | -}; |
373 | | -#endif // _LIBCPP_HAS_CHAR8_T |
374 | | - |
375 | | -template <> |
376 | | -struct hash<char16_t> : public __unary_function<char16_t, size_t> { |
377 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(char16_t __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
378 | | -}; |
379 | | - |
380 | | -template <> |
381 | | -struct hash<char32_t> : public __unary_function<char32_t, size_t> { |
382 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(char32_t __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
383 | | -}; |
384 | | - |
385 | | -#if _LIBCPP_HAS_WIDE_CHARACTERS |
386 | | -template <> |
387 | | -struct hash<wchar_t> : public __unary_function<wchar_t, size_t> { |
388 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(wchar_t __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
389 | | -}; |
390 | | -#endif // _LIBCPP_HAS_WIDE_CHARACTERS |
391 | | - |
392 | | -template <> |
393 | | -struct hash<short> : public __unary_function<short, size_t> { |
394 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(short __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
395 | | -}; |
396 | | - |
397 | | -template <> |
398 | | -struct hash<unsigned short> : public __unary_function<unsigned short, size_t> { |
399 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned short __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
400 | | -}; |
401 | | - |
402 | | -template <> |
403 | | -struct hash<int> : public __unary_function<int, size_t> { |
404 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(int __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
405 | | -}; |
406 | | - |
407 | | -template <> |
408 | | -struct hash<unsigned int> : public __unary_function<unsigned int, size_t> { |
409 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned int __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
| 357 | +template <class _Tp> |
| 358 | +struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value> > : __unary_function<_Tp, size_t> { |
| 359 | + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { |
| 360 | + using type = __underlying_type_t<_Tp>; |
| 361 | + return hash<type>()(static_cast<type>(__v)); |
| 362 | + } |
410 | 363 | }; |
411 | 364 |
|
412 | | -template <> |
413 | | -struct hash<long> : public __unary_function<long, size_t> { |
414 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(long __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
| 365 | +template <class _Tp> |
| 366 | +struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && sizeof(_Tp) <= sizeof(size_t)>> |
| 367 | + : __unary_function<_Tp, size_t> { |
| 368 | + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
415 | 369 | }; |
416 | 370 |
|
417 | | -template <> |
418 | | -struct hash<unsigned long> : public __unary_function<unsigned long, size_t> { |
419 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned long __v) const _NOEXCEPT { |
420 | | - static_assert(sizeof(size_t) >= sizeof(unsigned long), |
421 | | - "This would be a terrible hash function on a platform where size_t is smaller than unsigned long"); |
422 | | - return static_cast<size_t>(__v); |
423 | | - } |
| 371 | +template <class _Tp> |
| 372 | +struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) > sizeof(size_t))>> : __scalar_hash<_Tp> { |
424 | 373 | }; |
425 | 374 |
|
426 | | -template <> |
427 | | -struct hash<long long> : public __scalar_hash<long long> {}; |
428 | | - |
429 | | -template <> |
430 | | -struct hash<unsigned long long> : public __scalar_hash<unsigned long long> {}; |
431 | | - |
432 | | -#if _LIBCPP_HAS_INT128 |
433 | | - |
434 | | -template <> |
435 | | -struct hash<__int128_t> : public __scalar_hash<__int128_t> {}; |
436 | | - |
437 | | -template <> |
438 | | -struct hash<__uint128_t> : public __scalar_hash<__uint128_t> {}; |
439 | | - |
440 | | -#endif |
441 | | - |
442 | | -template <> |
443 | | -struct hash<float> : public __scalar_hash<float> { |
444 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(float __v) const _NOEXCEPT { |
| 375 | +template <class _Tp> |
| 376 | +struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value>> : __scalar_hash<_Tp> { |
| 377 | + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { |
445 | 378 | // -0.0 and 0.0 should return same hash |
446 | 379 | if (__v == 0.0f) |
447 | 380 | return 0; |
448 | | - return __scalar_hash<float>::operator()(__v); |
449 | | - } |
450 | | -}; |
451 | | - |
452 | | -template <> |
453 | | -struct hash<double> : public __scalar_hash<double> { |
454 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(double __v) const _NOEXCEPT { |
455 | | - // -0.0 and 0.0 should return same hash |
456 | | - if (__v == 0.0) |
457 | | - return 0; |
458 | | - return __scalar_hash<double>::operator()(__v); |
| 381 | + return __scalar_hash<_Tp>::operator()(__v); |
459 | 382 | } |
460 | 383 | }; |
461 | 384 |
|
462 | 385 | template <> |
463 | | -struct hash<long double> : public __scalar_hash<long double> { |
| 386 | +struct __hash_impl<long double, void> : __scalar_hash<long double> { |
464 | 387 | _LIBCPP_HIDE_FROM_ABI size_t operator()(long double __v) const _NOEXCEPT { |
465 | 388 | // -0.0 and 0.0 should return same hash |
466 | 389 | if (__v == 0.0L) |
@@ -501,22 +424,8 @@ struct hash<long double> : public __scalar_hash<long double> { |
501 | 424 | } |
502 | 425 | }; |
503 | 426 |
|
504 | | -template <class _Tp, bool = is_enum<_Tp>::value> |
505 | | -struct __enum_hash : public __unary_function<_Tp, size_t> { |
506 | | - _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { |
507 | | - using type = __underlying_type_t<_Tp>; |
508 | | - return hash<type>()(static_cast<type>(__v)); |
509 | | - } |
510 | | -}; |
511 | | -template <class _Tp> |
512 | | -struct __enum_hash<_Tp, false> { |
513 | | - __enum_hash() = delete; |
514 | | - __enum_hash(__enum_hash const&) = delete; |
515 | | - __enum_hash& operator=(__enum_hash const&) = delete; |
516 | | -}; |
517 | | - |
518 | 427 | template <class _Tp> |
519 | | -struct hash : public __enum_hash<_Tp> {}; |
| 428 | +struct hash : public __hash_impl<_Tp> {}; |
520 | 429 |
|
521 | 430 | #if _LIBCPP_STD_VER >= 17 |
522 | 431 |
|
|
0 commit comments