diff --git a/include/boost/container_hash/hash.hpp b/include/boost/container_hash/hash.hpp index 7b80f29..08b3a7e 100644 --- a/include/boost/container_hash/hash.hpp +++ b/include/boost/container_hash/hash.hpp @@ -17,7 +17,6 @@ #define BOOST_FUNCTIONAL_HASH_HASH_HPP #include -#include #include #include #include @@ -32,7 +31,9 @@ #include #include #include +#include #include +#include #if !defined(BOOST_NO_CXX11_SMART_PTR) # include @@ -75,8 +76,7 @@ namespace boost namespace hash_detail { - - template struct hash_integral_impl; + template sizeof(std::size_t)), bool size_t_64 = (sizeof(std::size_t) * CHAR_BIT >= 64)> struct hash_integral_impl; template struct hash_integral_impl { @@ -112,7 +112,7 @@ namespace boost typename boost::enable_if_::value, std::size_t>::type hash_value( T v ) { - return hash_detail::hash_integral_impl sizeof(std::size_t)), (sizeof(std::size_t) * CHAR_BIT >= 64)>::fn( v ); + return hash_detail::hash_integral_impl::fn( v ); } // enumeration types @@ -126,11 +126,75 @@ namespace boost // floating point types + namespace hash_detail + { + template::digits> struct hash_float_impl; + + // float + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint32_t w; + std::memcpy( &w, &v, sizeof( v ) ); + + return boost::hash_value( w ); + } + }; + + // double + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint64_t w; + std::memcpy( &w, &v, sizeof( v ) ); + + return boost::hash_value( w ); + } + }; + + // 80 bit long double + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint64_t w[ 2 ] = {}; + std::memcpy( &w, &v, 80 / CHAR_BIT ); + + std::size_t seed = 0; + + boost::hash_combine( seed, w[ 0 ] ); + boost::hash_combine( seed, w[ 1 ] ); + + return seed; + } + }; + + // 128 bit long double + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + boost::uint64_t w[ 2 ]; + std::memcpy( &w, &v, sizeof( v ) ); + + std::size_t seed = 0; + + boost::hash_combine( seed, w[ 0 ] ); + boost::hash_combine( seed, w[ 1 ] ); + + return seed; + } + }; + + } // namespace hash_detail + template typename boost::enable_if_::value, std::size_t>::type hash_value( T v ) { - return boost::hash_detail::float_hash_value( v ); + return boost::hash_detail::hash_float_impl::fn( v + 0 ); } // pointer types