aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2023-05-23 12:33:37 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2023-05-23 12:33:37 +0300
commitfc8394afe11d6c52ee148bef4fe547dc54105400 (patch)
tree1d8a9722ec3be9c35024c89b960b7ffc36ec2f26
parent6b15b52f9afb75de538a973b018d0fca823f8ba1 (diff)
downloadydb-fc8394afe11d6c52ee148bef4fe547dc54105400.tar.gz
Update contrib/restricted/boost/container_hash to 1.82.0
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_range.hpp333
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_tuple.hpp133
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/detail/hash_tuple_like.hpp156
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/detail/mulx.hpp79
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/detail/requires_cxx11.hpp22
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/hash.hpp19
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/hash_fwd.hpp1
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/is_contiguous_range.hpp1
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/is_range.hpp1
-rw-r--r--contrib/restricted/boost/container_hash/include/boost/container_hash/is_tuple_like.hpp42
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