diff options
author | Howard Hinnant <hhinnant@apple.com> | 2011-12-03 02:52:09 +0400 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2011-12-03 02:52:09 +0400 |
commit | 425d482c217ba30a1dbf1ae934f029983a0e9efe (patch) | |
tree | fd914020b6a83ba7dda231c87e263a56642b13b7 /libcxx/include/functional | |
parent | 4c3b8fb7e6ebee89ca758ae5b74e43c1fb81fc8a (diff) |
Fixes to hash for long long, unsigned long long, float, double and long double. Credit Dave Zarzycki
llvm-svn: 145721
Diffstat (limited to 'libcxx/include/functional')
-rw-r--r-- | libcxx/include/functional | 78 |
1 files changed, 56 insertions, 22 deletions
diff --git a/libcxx/include/functional b/libcxx/include/functional index 17a36cc87add..b5b08ab25a7c 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -1921,11 +1921,19 @@ struct _LIBCPP_VISIBLE hash<long long> _LIBCPP_INLINE_VISIBILITY size_t operator()(long long __v) const _NOEXCEPT { - size_t __r = 0; - const size_t* const __p = reinterpret_cast<const size_t*>(&__v); - for (unsigned __i = 0; __i < sizeof(argument_type)/sizeof(size_t); ++__i) - __r ^= __p[__i]; - return __r; +#ifdef __LP64__ + return __v; +#else + union { + long long __l; + struct { + int __a; + int __b; + } __s; + } __u; + __u.__l = __v; + return __u.__s.__a ^ __u.__s.__b; +#endif } }; @@ -1936,11 +1944,19 @@ struct _LIBCPP_VISIBLE hash<unsigned long long> _LIBCPP_INLINE_VISIBILITY size_t operator()(unsigned long long __v) const _NOEXCEPT { - size_t __r = 0; - const size_t* const __p = reinterpret_cast<const size_t*>(&__v); - for (unsigned __i = 0; __i < sizeof(argument_type)/sizeof(size_t); ++__i) - __r ^= __p[__i]; - return __r; +#ifdef __LP64__ + return __v; +#else + union { + unsigned long long __ul; + struct { + int __a; + int __b; + } __s; + } __u; + __u.__ul = __v; + return __u.__s.__a ^ __u.__s.__b; +#endif } }; @@ -1951,10 +1967,18 @@ struct _LIBCPP_VISIBLE hash<float> _LIBCPP_INLINE_VISIBILITY size_t operator()(float __v) const _NOEXCEPT { + union { +#ifdef __LP64__ + double __f; +#else + float __f; +#endif + size_t __d; + } __u; if (__v == 0) return 0; - const size_t* const __p = reinterpret_cast<const size_t*>(&__v); - return *__p; + __u.__f = __v; + return __u.__d; } }; @@ -1965,13 +1989,18 @@ struct _LIBCPP_VISIBLE hash<double> _LIBCPP_INLINE_VISIBILITY size_t operator()(double __v) const _NOEXCEPT { + union { +#ifdef __LP64__ + double __f; +#else + float __f; +#endif + size_t __d; + } __u; if (__v == 0) return 0; - size_t __r = 0; - const size_t* const __p = reinterpret_cast<const size_t*>(&__v); - for (unsigned __i = 0; __i < sizeof(argument_type)/sizeof(size_t); ++__i) - __r ^= __p[__i]; - return __r; + __u.__f = __v; + return __u.__d; } }; @@ -1982,13 +2011,18 @@ struct _LIBCPP_VISIBLE hash<long double> _LIBCPP_INLINE_VISIBILITY size_t operator()(long double __v) const _NOEXCEPT { + union { +#ifdef __LP64__ + double __f; +#else + float __f; +#endif + size_t __d; + } __u; if (__v == 0) return 0; - size_t __r = 0; - const size_t* const __p = reinterpret_cast<const size_t*>(&__v); - for (unsigned __i = 0; __i < sizeof(argument_type)/sizeof(size_t); ++__i) - __r ^= __p[__i]; - return __r; + __u.__f = __v; + return __u.__d; } }; |