From f8ecd668201d0bcc9e854dc913cc714204f97d69 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 12 Oct 2023 14:06:30 +0300 Subject: [PATCH] Move integrals to detail/hash_integral.hpp --- .../container_hash/detail/hash_integral.hpp | 102 ++++++++++++++++++ include/boost/container_hash/hash.hpp | 86 +-------------- 2 files changed, 104 insertions(+), 84 deletions(-) create mode 100644 include/boost/container_hash/detail/hash_integral.hpp diff --git a/include/boost/container_hash/detail/hash_integral.hpp b/include/boost/container_hash/detail/hash_integral.hpp new file mode 100644 index 0000000..ecac3c4 --- /dev/null +++ b/include/boost/container_hash/detail/hash_integral.hpp @@ -0,0 +1,102 @@ +// Copyright 2021-203 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP +#define BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP + +#include +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template sizeof(std::size_t)), + bool is_unsigned = std::is_unsigned::value, + std::size_t size_t_bits = sizeof(std::size_t) * CHAR_BIT, + std::size_t type_bits = sizeof(T) * CHAR_BIT> +struct hash_integral_impl; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + return static_cast( v ); + } +}; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + typedef typename std::make_unsigned::type U; + + if( v >= 0 ) + { + return hash_integral_impl::fn( static_cast( v ) ); + } + else + { + return ~hash_integral_impl::fn( static_cast( ~static_cast( v ) ) ); + } + } +}; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v & 0xFFFFFFFF ) + hash_detail::hash_mix( seed ); + + return seed; + } +}; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + seed = static_cast( v >> 96 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v ) + hash_detail::hash_mix( seed ); + + return seed; + } +}; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v ) + hash_detail::hash_mix( seed ); + + return seed; + } +}; + +} // namespace hash_detail + +template +typename std::enable_if::value, std::size_t>::type + hash_value( T v ) +{ + return hash_detail::hash_integral_impl::fn( v ); +} + +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP diff --git a/include/boost/container_hash/hash.hpp b/include/boost/container_hash/hash.hpp index f523c96..36bd1bc 100644 --- a/include/boost/container_hash/hash.hpp +++ b/include/boost/container_hash/hash.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -67,90 +68,7 @@ namespace boost // // integral types - - namespace hash_detail - { - template sizeof(std::size_t)), - bool is_unsigned = std::is_unsigned::value, - std::size_t size_t_bits = sizeof(std::size_t) * CHAR_BIT, - std::size_t type_bits = sizeof(T) * CHAR_BIT> - struct hash_integral_impl; - - template struct hash_integral_impl - { - static std::size_t fn( T v ) - { - return static_cast( v ); - } - }; - - template struct hash_integral_impl - { - static std::size_t fn( T v ) - { - typedef typename std::make_unsigned::type U; - - if( v >= 0 ) - { - return hash_integral_impl::fn( static_cast( v ) ); - } - else - { - return ~hash_integral_impl::fn( static_cast( ~static_cast( v ) ) ); - } - } - }; - - template struct hash_integral_impl - { - static std::size_t fn( T v ) - { - std::size_t seed = 0; - - seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); - seed = static_cast( v & 0xFFFFFFFF ) + hash_detail::hash_mix( seed ); - - return seed; - } - }; - - template struct hash_integral_impl - { - static std::size_t fn( T v ) - { - std::size_t seed = 0; - - seed = static_cast( v >> 96 ) + hash_detail::hash_mix( seed ); - seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); - seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); - seed = static_cast( v ) + hash_detail::hash_mix( seed ); - - return seed; - } - }; - - template struct hash_integral_impl - { - static std::size_t fn( T v ) - { - std::size_t seed = 0; - - seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); - seed = static_cast( v ) + hash_detail::hash_mix( seed ); - - return seed; - } - }; - - } // namespace hash_detail - - template - typename std::enable_if::value, std::size_t>::type - hash_value( T v ) - { - return hash_detail::hash_integral_impl::fn( v ); - } + // in detail/hash_integral.hpp // enumeration types