1// Copyright 2005-2009 Daniel James.
2// Copyright 2021 Peter Dimov.
3// Distributed under the Boost Software License, Version 1.0.
4// https://www.boost.org/LICENSE_1_0.txt
5
6#ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
7#define BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
8
9#include <boost/container_hash/hash_fwd.hpp>
10#include <boost/container_hash/is_tuple_like.hpp>
11#include <boost/container_hash/is_range.hpp>
12#include <boost/type_traits/enable_if.hpp>
13#include <boost/config.hpp>
14#include <boost/config/workaround.hpp>
15
16#if defined(BOOST_NO_CXX11_HDR_TUPLE)
17
18// no support for tuple-likes
19
20#else
21
22#include <tuple>
23
24namespace boost
25{
26namespace hash_detail
27{
28
29template <std::size_t I, typename T>
30inline
31typename boost::enable_if_<(I == std::tuple_size<T>::value), void>::type
32 hash_combine_tuple_like( std::size_t&, T const& )
33{
34}
35
36template <std::size_t I, typename T>
37inline
38typename boost::enable_if_<(I < std::tuple_size<T>::value), void>::type
39 hash_combine_tuple_like( std::size_t& seed, T const& v )
40{
41 using std::get;
42 boost::hash_combine( seed, get<I>( v ) );
43
44 boost::hash_detail::hash_combine_tuple_like<I + 1>( seed, v );
45}
46
47template <typename T>
48inline std::size_t hash_tuple_like( T const& v )
49{
50 std::size_t seed = 0;
51
52 boost::hash_detail::hash_combine_tuple_like<0>( seed, v );
53
54 return seed;
55}
56
57} // namespace hash_detail
58
59#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
60
61#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1800)
62
63template <class T>
64inline
65typename boost::enable_if_<
66 container_hash::is_tuple_like<T>::value && !container_hash::is_range<T>::value,
67std::size_t>::type
68 hash_value( T const& v )
69{
70 return boost::hash_detail::hash_tuple_like( v );
71}
72
73#else
74
75template <typename... T>
76inline std::size_t hash_value( std::tuple<T...> const& v )
77{
78 return boost::hash_detail::hash_tuple_like( v );
79}
80
81#endif
82
83#else
84
85inline std::size_t hash_value( std::tuple<> const& v )
86{
87 return boost::hash_detail::hash_tuple_like( v );
88}
89
90template<typename A0>
91inline std::size_t hash_value( std::tuple<A0> const& v )
92{
93 return boost::hash_detail::hash_tuple_like( v );
94}
95
96template<typename A0, typename A1>
97inline std::size_t hash_value( std::tuple<A0, A1> const& v )
98{
99 return boost::hash_detail::hash_tuple_like( v );
100}
101
102template<typename A0, typename A1, typename A2>
103inline std::size_t hash_value( std::tuple<A0, A1, A2> const& v )
104{
105 return boost::hash_detail::hash_tuple_like( v );
106}
107
108template<typename A0, typename A1, typename A2, typename A3>
109inline std::size_t hash_value( std::tuple<A0, A1, A2, A3> const& v )
110{
111 return boost::hash_detail::hash_tuple_like( v );
112}
113
114template<typename A0, typename A1, typename A2, typename A3, typename A4>
115inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4> const& v )
116{
117 return boost::hash_detail::hash_tuple_like( v );
118}
119
120template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
121inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5> const& v )
122{
123 return boost::hash_detail::hash_tuple_like( v );
124}
125
126template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
127inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5, A6> const& v )
128{
129 return boost::hash_detail::hash_tuple_like( v );
130}
131
132template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
133inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5, A6, A7> const& v )
134{
135 return boost::hash_detail::hash_tuple_like( v );
136}
137
138template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
139inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8> const& v )
140{
141 return boost::hash_detail::hash_tuple_like( v );
142}
143
144template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
145inline std::size_t hash_value( std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9> const& v )
146{
147 return boost::hash_detail::hash_tuple_like( v );
148}
149
150#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
151
152} // namespace boost
153
154#endif // #if defined(BOOST_NO_CXX11_HDR_TUPLE)
155
156#endif // #ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
157