diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2023-05-23 12:33:37 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2023-05-23 12:33:37 +0300 |
commit | fc8394afe11d6c52ee148bef4fe547dc54105400 (patch) | |
tree | 1d8a9722ec3be9c35024c89b960b7ffc36ec2f26 | |
parent | 6b15b52f9afb75de538a973b018d0fca823f8ba1 (diff) | |
download | ydb-fc8394afe11d6c52ee148bef4fe547dc54105400.tar.gz |
Update contrib/restricted/boost/container_hash to 1.82.0
10 files changed, 604 insertions, 183 deletions
diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_range.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_range.hpp index 28fd239ea6..84ec97da58 100644 --- a/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_range.hpp +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_range.hpp @@ -6,13 +6,16 @@ #define BOOST_HASH_DETAIL_HASH_RANGE_HPP #include <boost/container_hash/hash_fwd.hpp> +#include <boost/container_hash/detail/mulx.hpp> #include <boost/type_traits/integral_constant.hpp> #include <boost/type_traits/enable_if.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/cstdint.hpp> +#include <iterator> +#include <limits> #include <cstddef> #include <climits> -#include <iterator> +#include <cstring> namespace boost { @@ -37,6 +40,8 @@ template<> struct is_char_type<std::byte>: public boost::true_type {}; #endif +// generic version + template<class It> inline typename boost::enable_if_< !is_char_type<typename std::iterator_traits<It>::value_type>::value, @@ -51,120 +56,352 @@ std::size_t >::type return seed; } +// specialized char[] version, 32 bit + +template<class It> inline boost::uint32_t read32le( It p ) +{ + // clang 5+, gcc 5+ figure out this pattern and use a single mov on x86 + // gcc on s390x and power BE even knows how to use load-reverse + + boost::uint32_t w = + static_cast<boost::uint32_t>( static_cast<unsigned char>( p[0] ) ) | + static_cast<boost::uint32_t>( static_cast<unsigned char>( p[1] ) ) << 8 | + static_cast<boost::uint32_t>( static_cast<unsigned char>( p[2] ) ) << 16 | + static_cast<boost::uint32_t>( static_cast<unsigned char>( p[3] ) ) << 24; + + return w; +} + +#if defined(_MSC_VER) && !defined(__clang__) + +template<class T> inline boost::uint32_t read32le( T* p ) +{ + boost::uint32_t w; + + std::memcpy( &w, p, 4 ); + return w; +} + +#endif + +inline boost::uint64_t mul32( boost::uint32_t x, boost::uint32_t y ) +{ + return static_cast<boost::uint64_t>( x ) * y; +} + template<class It> inline typename boost::enable_if_< is_char_type<typename std::iterator_traits<It>::value_type>::value && - is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value, + is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value && + std::numeric_limits<std::size_t>::digits <= 32, std::size_t>::type hash_range( std::size_t seed, It first, It last ) { + It p = first; std::size_t n = static_cast<std::size_t>( last - first ); - for( ; n >= 4; first += 4, n -= 4 ) + boost::uint32_t const q = 0x9e3779b9U; + boost::uint32_t const k = 0xe35e67b1U; // q * q + + boost::uint64_t h = mul32( static_cast<boost::uint32_t>( seed ) + q, k ); + boost::uint32_t w = static_cast<boost::uint32_t>( h & 0xFFFFFFFF ); + + h ^= n; + + while( n >= 4 ) { - // clang 5+, gcc 5+ figure out this pattern and use a single mov on x86 - // gcc on s390x and power BE even knows how to use load-reverse + boost::uint32_t v1 = read32le( p ); - boost::uint32_t w = - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[0] ) ) | - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[1] ) ) << 8 | - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[2] ) ) << 16 | - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[3] ) ) << 24; + w += q; + h ^= mul32( v1 + w, k ); - hash_combine( seed, w ); + p += 4; + n -= 4; } { - // add a trailing suffix byte of 0x01 because otherwise sequences of - // trailing zeroes are indistinguishable from end of string + boost::uint32_t v1 = 0; + + if( n >= 1 ) + { + std::size_t const x1 = ( n - 1 ) & 2; // 1: 0, 2: 0, 3: 2 + std::size_t const x2 = n >> 1; // 1: 0, 2: 1, 3: 1 + + v1 = + static_cast<boost::uint32_t>( static_cast<unsigned char>( p[ static_cast<std::ptrdiff_t>( x1 ) ] ) ) << x1 * 8 | + static_cast<boost::uint32_t>( static_cast<unsigned char>( p[ static_cast<std::ptrdiff_t>( x2 ) ] ) ) << x2 * 8 | + static_cast<boost::uint32_t>( static_cast<unsigned char>( p[ 0 ] ) ); + } + + w += q; + h ^= mul32( v1 + w, k ); + } + + w += q; + h ^= mul32( static_cast<boost::uint32_t>( h & 0xFFFFFFFF ) + w, static_cast<boost::uint32_t>( h >> 32 ) + w + k ); + + return static_cast<boost::uint32_t>( h & 0xFFFFFFFF ) ^ static_cast<boost::uint32_t>( h >> 32 ); +} + +template<class It> +inline typename boost::enable_if_< + is_char_type<typename std::iterator_traits<It>::value_type>::value && + !is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value && + std::numeric_limits<std::size_t>::digits <= 32, +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + std::size_t n = 0; + + boost::uint32_t const q = 0x9e3779b9U; + boost::uint32_t const k = 0xe35e67b1U; // q * q + + boost::uint64_t h = mul32( static_cast<boost::uint32_t>( seed ) + q, k ); + boost::uint32_t w = static_cast<boost::uint32_t>( h & 0xFFFFFFFF ); - boost::uint32_t w = 0x01u; + boost::uint32_t v1 = 0; - switch( n ) + for( ;; ) + { + v1 = 0; + + if( first == last ) { - case 1: + break; + } - w = - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[0] ) ) | - 0x0100u; + v1 |= static_cast<boost::uint32_t>( static_cast<unsigned char>( *first ) ); + ++first; + ++n; + if( first == last ) + { break; + } - case 2: + v1 |= static_cast<boost::uint32_t>( static_cast<unsigned char>( *first ) ) << 8; + ++first; + ++n; - w = - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[0] ) ) | - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[1] ) ) << 8 | - 0x010000u; + if( first == last ) + { + break; + } + v1 |= static_cast<boost::uint32_t>( static_cast<unsigned char>( *first ) ) << 16; + ++first; + ++n; + + if( first == last ) + { break; + } - case 3: + v1 |= static_cast<boost::uint32_t>( static_cast<unsigned char>( *first ) ) << 24; + ++first; + ++n; - w = - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[0] ) ) | - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[1] ) ) << 8 | - static_cast<boost::uint32_t>( static_cast<unsigned char>( first[2] ) ) << 16 | - 0x01000000u; + w += q; + h ^= mul32( v1 + w, k ); + } - break; + h ^= n; + + w += q; + h ^= mul32( v1 + w, k ); + + w += q; + h ^= mul32( static_cast<boost::uint32_t>( h & 0xFFFFFFFF ) + w, static_cast<boost::uint32_t>( h >> 32 ) + w + k ); + + return static_cast<boost::uint32_t>( h & 0xFFFFFFFF ) ^ static_cast<boost::uint32_t>( h >> 32 ); +} + +// specialized char[] version, 64 bit + +template<class It> inline boost::uint64_t read64le( It p ) +{ + boost::uint64_t w = + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[0] ) ) | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[1] ) ) << 8 | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[2] ) ) << 16 | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[3] ) ) << 24 | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[4] ) ) << 32 | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[5] ) ) << 40 | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[6] ) ) << 48 | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[7] ) ) << 56; + + return w; +} + +#if defined(_MSC_VER) && !defined(__clang__) + +template<class T> inline boost::uint64_t read64le( T* p ) +{ + boost::uint64_t w; + + std::memcpy( &w, p, 8 ); + return w; +} + +#endif + +template<class It> +inline typename boost::enable_if_< + is_char_type<typename std::iterator_traits<It>::value_type>::value && + is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value && + (std::numeric_limits<std::size_t>::digits > 32), +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + It p = first; + std::size_t n = static_cast<std::size_t>( last - first ); + + boost::uint64_t const q = static_cast<boost::uint64_t>( 0x9e3779b9 ) << 32 | 0x7f4a7c15; + boost::uint64_t const k = static_cast<boost::uint64_t>( 0xdf442d22 ) << 32 | 0xce4859b9; // q * q + + boost::uint64_t w = mulx( seed + q, k ); + boost::uint64_t h = w ^ n; + + while( n >= 8 ) + { + boost::uint64_t v1 = read64le( p ); + + w += q; + h ^= mulx( v1 + w, k ); + + p += 8; + n -= 8; + } + + { + boost::uint64_t v1 = 0; + + if( n >= 4 ) + { + v1 = static_cast<boost::uint64_t>( read32le( p + static_cast<std::ptrdiff_t>( n - 4 ) ) ) << ( n - 4 ) * 8 | read32le( p ); + } + else if( n >= 1 ) + { + std::size_t const x1 = ( n - 1 ) & 2; // 1: 0, 2: 0, 3: 2 + std::size_t const x2 = n >> 1; // 1: 0, 2: 1, 3: 1 + + v1 = + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[ static_cast<std::ptrdiff_t>( x1 ) ] ) ) << x1 * 8 | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[ static_cast<std::ptrdiff_t>( x2 ) ] ) ) << x2 * 8 | + static_cast<boost::uint64_t>( static_cast<unsigned char>( p[ 0 ] ) ); } - hash_combine( seed, w ); + w += q; + h ^= mulx( v1 + w, k ); } - return seed; + return mulx( h + w, k ); } template<class It> inline typename boost::enable_if_< is_char_type<typename std::iterator_traits<It>::value_type>::value && - !is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value, + !is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value && + (std::numeric_limits<std::size_t>::digits > 32), std::size_t>::type hash_range( std::size_t seed, It first, It last ) { + std::size_t n = 0; + + boost::uint64_t const q = static_cast<boost::uint64_t>( 0x9e3779b9 ) << 32 | 0x7f4a7c15; + boost::uint64_t const k = static_cast<boost::uint64_t>( 0xdf442d22 ) << 32 | 0xce4859b9; // q * q + + boost::uint64_t w = mulx( seed + q, k ); + boost::uint64_t h = w; + + boost::uint64_t v1 = 0; + for( ;; ) { - boost::uint32_t w = 0; + v1 = 0; if( first == last ) { - hash_combine( seed, w | 0x01u ); - return seed; + break; + } + + v1 |= static_cast<boost::uint64_t>( static_cast<unsigned char>( *first ) ); + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast<boost::uint64_t>( static_cast<unsigned char>( *first ) ) << 8; + ++first; + ++n; + + if( first == last ) + { + break; } - w |= static_cast<boost::uint32_t>( static_cast<unsigned char>( *first ) ); + v1 |= static_cast<boost::uint64_t>( static_cast<unsigned char>( *first ) ) << 16; ++first; + ++n; if( first == last ) { - hash_combine( seed, w | 0x0100u ); - return seed; + break; } - w |= static_cast<boost::uint32_t>( static_cast<unsigned char>( *first ) ) << 8; + v1 |= static_cast<boost::uint64_t>( static_cast<unsigned char>( *first ) ) << 24; ++first; + ++n; if( first == last ) { - hash_combine( seed, w | 0x010000u ); - return seed; + break; } - w |= static_cast<boost::uint32_t>( static_cast<unsigned char>( *first ) ) << 16; + v1 |= static_cast<boost::uint64_t>( static_cast<unsigned char>( *first ) ) << 32; ++first; + ++n; if( first == last ) { - hash_combine( seed, w | 0x01000000u ); - return seed; + break; } - w |= static_cast<boost::uint32_t>( static_cast<unsigned char>( *first ) ) << 24; + v1 |= static_cast<boost::uint64_t>( static_cast<unsigned char>( *first ) ) << 40; ++first; + ++n; - hash_combine( seed, w ); + if( first == last ) + { + break; + } + + v1 |= static_cast<boost::uint64_t>( static_cast<unsigned char>( *first ) ) << 48; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast<boost::uint64_t>( static_cast<unsigned char>( *first ) ) << 56; + ++first; + ++n; + + w += q; + h ^= mulx( v1 + w, k ); } + + h ^= n; + + w += q; + h ^= mulx( v1 + w, k ); + + return mulx( h + w, k ); } } // namespace hash_detail diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_tuple.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_tuple.hpp deleted file mode 100644 index 597cee9d9e..0000000000 --- a/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_tuple.hpp +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2005-2009 Daniel James. -// Copyright 2021 Peter Dimov. -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP -#define BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP - -#include <boost/container_hash/hash_fwd.hpp> -#include <boost/type_traits/enable_if.hpp> -#include <boost/config.hpp> - -#if defined(BOOST_NO_CXX11_HDR_TUPLE) - -// no support - -#else - -#include <tuple> - -namespace boost -{ -namespace hash_detail -{ - -template <std::size_t I, typename T> -inline typename boost::enable_if_<(I == std::tuple_size<T>::value), - void>::type - hash_combine_tuple(std::size_t&, T const&) -{ -} - -template <std::size_t I, typename T> -inline typename boost::enable_if_<(I < std::tuple_size<T>::value), - void>::type - hash_combine_tuple(std::size_t& seed, T const& v) -{ - boost::hash_combine(seed, std::get<I>(v)); - boost::hash_detail::hash_combine_tuple<I + 1>(seed, v); -} - -template <typename T> -inline std::size_t hash_tuple(T const& v) -{ - std::size_t seed = 0; - boost::hash_detail::hash_combine_tuple<0>(seed, v); - return seed; -} - -} // namespace hash_detail - -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -template <typename... T> -inline std::size_t hash_value(std::tuple<T...> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -#else - -inline std::size_t hash_value(std::tuple<> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0> -inline std::size_t hash_value(std::tuple<A0> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1> -inline std::size_t hash_value(std::tuple<A0, A1> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1, typename A2> -inline std::size_t hash_value(std::tuple<A0, A1, A2> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1, typename A2, typename A3> -inline std::size_t hash_value(std::tuple<A0, A1, A2, A3> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1, typename A2, typename A3, typename A4> -inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> -inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> -inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> -inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> -inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> -inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9> const& v) -{ - return boost::hash_detail::hash_tuple(v); -} - -#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -} // namespace boost - -#endif // #if defined(BOOST_NO_CXX11_HDR_TUPLE) - -#endif // #ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_tuple_like.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_tuple_like.hpp new file mode 100644 index 0000000000..f9f5a5bae8 --- /dev/null +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_tuple_like.hpp @@ -0,0 +1,156 @@ +// Copyright 2005-2009 Daniel James. +// Copyright 2021 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP +#define BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP + +#include <boost/container_hash/hash_fwd.hpp> +#include <boost/container_hash/is_tuple_like.hpp> +#include <boost/container_hash/is_range.hpp> +#include <boost/type_traits/enable_if.hpp> +#include <boost/config.hpp> +#include <boost/config/workaround.hpp> + +#if defined(BOOST_NO_CXX11_HDR_TUPLE) + +// no support for tuple-likes + +#else + +#include <tuple> + +namespace boost +{ +namespace hash_detail +{ + +template <std::size_t I, typename T> +inline +typename boost::enable_if_<(I == std::tuple_size<T>::value), void>::type + hash_combine_tuple_like( std::size_t&, T const& ) +{ +} + +template <std::size_t I, typename T> +inline +typename boost::enable_if_<(I < std::tuple_size<T>::value), void>::type + hash_combine_tuple_like( std::size_t& seed, T const& v ) +{ + using std::get; + boost::hash_combine( seed, get<I>( v ) ); + + boost::hash_detail::hash_combine_tuple_like<I + 1>( seed, v ); +} + +template <typename T> +inline std::size_t hash_tuple_like( T const& v ) +{ + std::size_t seed = 0; + + boost::hash_detail::hash_combine_tuple_like<0>( seed, v ); + + return seed; +} + +} // namespace hash_detail + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1800) + +template <class T> +inline +typename boost::enable_if_< + container_hash::is_tuple_like<T>::value && !container_hash::is_range<T>::value, +std::size_t>::type + hash_value( T const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +#else + +template <typename... T> +inline std::size_t hash_value( std::tuple<T...> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +#endif + +#else + +inline std::size_t hash_value( std::tuple<> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0> +inline std::size_t hash_value( std::tuple<A0> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1> +inline std::size_t hash_value( std::tuple<A0, A1> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1, typename A2> +inline std::size_t hash_value( std::tuple<A0, A1, A2> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1, typename A2, typename A3> +inline std::size_t hash_value( std::tuple<A0, A1, A2, A3> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1, typename A2, typename A3, typename A4> +inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> +inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> +inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5, A6> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> +inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5, A6, A7> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> +inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> +inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9> const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +} // namespace boost + +#endif // #if defined(BOOST_NO_CXX11_HDR_TUPLE) + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/mulx.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/mulx.hpp new file mode 100644 index 0000000000..da6f21a245 --- /dev/null +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/mulx.hpp @@ -0,0 +1,79 @@ +// Copyright 2022, 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_MULX_HPP +#define BOOST_HASH_DETAIL_MULX_HPP + +#include <boost/cstdint.hpp> +#if defined(_MSC_VER) +# include <intrin.h> +#endif + +namespace boost +{ +namespace hash_detail +{ + +#if defined(_MSC_VER) && defined(_M_X64) && !defined(__clang__) + +__forceinline boost::uint64_t mulx( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t r2; + boost::uint64_t r = _umul128( x, y, &r2 ); + return r ^ r2; +} + +#elif defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) + +__forceinline boost::uint64_t mulx( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t r = x * y; + boost::uint64_t r2 = __umulh( x, y ); + return r ^ r2; +} + +#elif defined(__SIZEOF_INT128__) + +inline boost::uint64_t mulx( boost::uint64_t x, boost::uint64_t y ) +{ + __uint128_t r = static_cast<__uint128_t>( x ) * y; + return static_cast<boost::uint64_t>( r ) ^ static_cast<boost::uint64_t>( r >> 64 ); +} + +#else + +inline boost::uint64_t mulx( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t x1 = static_cast<boost::uint32_t>( x ); + boost::uint64_t x2 = x >> 32; + + boost::uint64_t y1 = static_cast<boost::uint32_t>( y ); + boost::uint64_t y2 = y >> 32; + + boost::uint64_t r3 = x2 * y2; + + boost::uint64_t r2a = x1 * y2; + + r3 += r2a >> 32; + + boost::uint64_t r2b = x2 * y1; + + r3 += r2b >> 32; + + boost::uint64_t r1 = x1 * y1; + + boost::uint64_t r2 = (r1 >> 32) + static_cast<boost::uint32_t>( r2a ) + static_cast<boost::uint32_t>( r2b ); + + r1 = (r2 << 32) + static_cast<boost::uint32_t>( r1 ); + r3 += r2 >> 32; + + return r1 ^ r3; +} + +#endif + +} // namespace hash_detail +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_MULX_HPP diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/requires_cxx11.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/requires_cxx11.hpp new file mode 100644 index 0000000000..61db135bc2 --- /dev/null +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/detail/requires_cxx11.hpp @@ -0,0 +1,22 @@ +#ifndef BOOST_HASH_DETAIL_REQUIRES_CXX11_HPP_INCLUDED +#define BOOST_HASH_DETAIL_REQUIRES_CXX11_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include <boost/config.hpp> +#include <boost/config/pragma_message.hpp> + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \ + defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ + defined(BOOST_NO_CXX11_DECLTYPE) || \ + defined(BOOST_NO_CXX11_CONSTEXPR) || \ + defined(BOOST_NO_CXX11_NOEXCEPT) || \ + defined(BOOST_NO_CXX11_HDR_TUPLE) + +BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.ContainerHash 1.82 and will be removed in Boost.ContainerHash 1.84.") + +#endif + +#endif // #ifndef BOOST_HASH_DETAIL_REQUIRES_CXX11_HPP_INCLUDED diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/hash.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/hash.hpp index 306c279164..605644b35d 100644 --- a/contrib/restricted/boost/container_hash/include/boost/container_hash/hash.hpp +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/hash.hpp @@ -11,11 +11,12 @@ #define BOOST_FUNCTIONAL_HASH_HASH_HPP #include <boost/container_hash/hash_fwd.hpp> +#include <boost/container_hash/detail/requires_cxx11.hpp> #include <boost/container_hash/is_range.hpp> #include <boost/container_hash/is_contiguous_range.hpp> #include <boost/container_hash/is_unordered_range.hpp> #include <boost/container_hash/is_described_class.hpp> -#include <boost/container_hash/detail/hash_tuple.hpp> +#include <boost/container_hash/detail/hash_tuple_like.hpp> #include <boost/container_hash/detail/hash_mix.hpp> #include <boost/container_hash/detail/hash_range.hpp> #include <boost/type_traits/is_enum.hpp> @@ -27,6 +28,7 @@ #include <boost/type_traits/enable_if.hpp> #include <boost/type_traits/conjunction.hpp> #include <boost/type_traits/is_union.hpp> +#include <boost/type_traits/is_same.hpp> #include <boost/describe/bases.hpp> #include <boost/describe/members.hpp> #include <boost/cstdint.hpp> @@ -117,7 +119,7 @@ namespace boost std::size_t seed = 0; seed = static_cast<std::size_t>( v >> 32 ) + hash_detail::hash_mix( seed ); - seed = static_cast<std::size_t>( v ) + hash_detail::hash_mix( seed ); + seed = static_cast<std::size_t>( v & 0xFFFFFFFF ) + hash_detail::hash_mix( seed ); return seed; } @@ -496,6 +498,19 @@ namespace boost #endif + // std::nullptr_t + +#if !defined(BOOST_NO_CXX11_NULLPTR) + + template <typename T> + typename boost::enable_if_<boost::is_same<T, std::nullptr_t>::value, std::size_t>::type + hash_value( T const& /*v*/ ) + { + return boost::hash_value( static_cast<void*>( nullptr ) ); + } + +#endif + // std::optional #if !defined(BOOST_NO_CXX17_HDR_OPTIONAL) diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/hash_fwd.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/hash_fwd.hpp index 489fdd2314..32388ac545 100644 --- a/contrib/restricted/boost/container_hash/include/boost/container_hash/hash_fwd.hpp +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/hash_fwd.hpp @@ -18,6 +18,7 @@ template<class T> struct is_range; template<class T> struct is_contiguous_range; template<class T> struct is_unordered_range; template<class T> struct is_described_class; +template<class T> struct is_tuple_like; } // namespace container_hash diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/is_contiguous_range.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/is_contiguous_range.hpp index 0e31c11085..96043ccd5f 100644 --- a/contrib/restricted/boost/container_hash/include/boost/container_hash/is_contiguous_range.hpp +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/is_contiguous_range.hpp @@ -5,6 +5,7 @@ #ifndef BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED #define BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED +#include <boost/container_hash/detail/requires_cxx11.hpp> #include <boost/container_hash/is_range.hpp> #include <boost/type_traits/integral_constant.hpp> #include <boost/config.hpp> diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/is_range.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/is_range.hpp index 56fbd2e794..2d3746cd2b 100644 --- a/contrib/restricted/boost/container_hash/include/boost/container_hash/is_range.hpp +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/is_range.hpp @@ -5,6 +5,7 @@ #ifndef BOOST_HASH_IS_RANGE_HPP_INCLUDED #define BOOST_HASH_IS_RANGE_HPP_INCLUDED +#include <boost/container_hash/detail/requires_cxx11.hpp> #include <boost/type_traits/integral_constant.hpp> #include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/declval.hpp> diff --git a/contrib/restricted/boost/container_hash/include/boost/container_hash/is_tuple_like.hpp b/contrib/restricted/boost/container_hash/include/boost/container_hash/is_tuple_like.hpp new file mode 100644 index 0000000000..8f57364e29 --- /dev/null +++ b/contrib/restricted/boost/container_hash/include/boost/container_hash/is_tuple_like.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED +#define BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED + +// Copyright 2017, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include <boost/type_traits/integral_constant.hpp> +#include <boost/config.hpp> +#include <boost/config/workaround.hpp> +#include <utility> + +namespace boost +{ +namespace hash_detail +{ + +template<class T, class E = true_type> struct is_tuple_like_: false_type +{ +}; + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1800) + +template<class T> struct is_tuple_like_<T, integral_constant<bool, std::tuple_size<T>::value == std::tuple_size<T>::value> >: true_type +{ +}; + +#endif + +} // namespace hash_detail + +namespace container_hash +{ + +template<class T> struct is_tuple_like: hash_detail::is_tuple_like_<T> +{ +}; + +} // namespace container_hash +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED |