From a2dab8c7d324972e22fb13a1dc8b8e137dddff8b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 13 Mar 2021 04:10:41 +0200 Subject: [PATCH] Refactor detail::hash_value_L --- include/boost/variant2/variant.hpp | 50 ++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 06a0419..901438d 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -26,6 +26,7 @@ #include #include #include // std::hash +#include // @@ -2195,28 +2196,51 @@ void swap( variant & v, variant & w ) namespace detail { +inline std::size_t hash_value_impl_( mp11::mp_true, std::size_t index, std::size_t value ) +{ + boost::ulong_long_type hv = ( boost::ulong_long_type( 0xCBF29CE4 ) << 32 ) + 0x84222325; + boost::ulong_long_type const prime = ( boost::ulong_long_type( 0x00000100 ) << 32 ) + 0x000001B3; + + hv ^= index; + hv *= prime; + + hv ^= value; + hv *= prime; + + return static_cast( hv ); +} + +inline std::size_t hash_value_impl_( mp11::mp_false, std::size_t index, std::size_t value ) +{ + std::size_t hv = 0x811C9DC5; + std::size_t const prime = 0x01000193; + + hv ^= index; + hv *= prime; + + hv ^= value; + hv *= prime; + + return hv; +} + +inline std::size_t hash_value_impl( std::size_t index, std::size_t value ) +{ + return hash_value_impl_( mp11::mp_bool< (SIZE_MAX > UINT32_MAX) >(), index, value ); +} + template struct hash_value_L { V const & v; template std::size_t operator()( I ) const { - boost::ulong_long_type hv = ( boost::ulong_long_type( 0xCBF29CE4 ) << 32 ) + 0x84222325; - boost::ulong_long_type const prime = ( boost::ulong_long_type( 0x00000100 ) << 32 ) + 0x000001B3; - - // index - - hv ^= I::value; - hv *= prime; - - // value - auto const & t = unsafe_get( v ); - hv ^= std::hash>()( t ); - hv *= prime; + std::size_t index = I::value; + std::size_t value = std::hash>()( t ); - return static_cast( hv ); + return hash_value_impl( index, value ); } };