1// Copyright 2022 Peter Dimov.
2// Distributed under the Boost Software License, Version 1.0.
3// https://www.boost.org/LICENSE_1_0.txt
4
5#if defined(__clang__)
6# pragma clang diagnostic ignored "-Wmismatched-tags"
7#endif
8
9#include <boost/container_hash/hash.hpp>
10#include <boost/core/lightweight_test.hpp>
11#include <boost/type_traits/enable_if.hpp>
12#include <boost/type_traits/is_same.hpp>
13#include <boost/type_traits/integral_constant.hpp>
14#include <boost/config.hpp>
15#include <utility>
16
17#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
18
19#include <tuple>
20
21namespace user
22{
23
24struct Y1
25{
26 int a;
27 int b;
28};
29
30template<std::size_t I> int& get( Y1& v );
31template<std::size_t I> int const& get( Y1 const& v );
32
33template<> int& get<0>( Y1& v )
34{
35 return v.a;
36}
37
38template<> int const& get<0>( Y1 const& v )
39{
40 return v.a;
41}
42
43template<> int& get<1>( Y1& v )
44{
45 return v.b;
46}
47
48template<> int const& get<1>( Y1 const& v )
49{
50 return v.b;
51}
52
53struct Y2
54{
55 int a;
56 int b;
57
58 template<class T> friend
59 typename boost::enable_if_<boost::is_same<T, Y2>::value, std::size_t>::type
60 hash_value( T const& v )
61 {
62 std::size_t seed = 0;
63
64 boost::hash_combine( seed, v.a );
65 boost::hash_combine( seed, v.b );
66
67 return seed;
68 }
69};
70
71} // namespace user
72
73namespace std
74{
75
76template<> struct tuple_size<user::Y1>: std::integral_constant<std::size_t, 2>
77{
78};
79
80template<> struct tuple_size<user::Y2>: std::integral_constant<std::size_t, 2>
81{
82};
83
84} // namespace std
85
86namespace boost
87{
88namespace container_hash
89{
90
91 template<> struct is_tuple_like<user::Y2>: boost::false_type {};
92
93} // namespace container_hash
94} // namespace boost
95
96#endif
97
98template<class T> std::size_t hv( T const& t )
99{
100 return boost::hash<T>()( t );
101}
102
103int main()
104{
105 {
106 std::pair<int, int> tp( 1, 2 );
107 int const a[] = { 1, 2 };
108
109 BOOST_TEST_EQ( hv(tp), hv(a) );
110 }
111
112#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
113
114 {
115 std::tuple<> tp;
116
117 BOOST_TEST_EQ( hv(tp), 0u );
118 }
119
120 {
121 std::tuple<int> tp( 1 );
122 int const a[] = { 1 };
123
124 BOOST_TEST_EQ( hv(tp), hv(a) );
125 }
126
127 {
128 std::tuple<int, int> tp( 1, 2 );
129 int const a[] = { 1, 2 };
130
131 BOOST_TEST_EQ( hv(tp), hv(a) );
132 }
133
134 {
135 std::tuple<int, int, int> tp( 1, 2, 3 );
136 int const a[] = { 1, 2, 3 };
137
138 BOOST_TEST_EQ( hv(tp), hv(a) );
139 }
140
141 {
142 std::tuple<int, int, int, int> tp( 1, 2, 3, 4 );
143 int const a[] = { 1, 2, 3, 4 };
144
145 BOOST_TEST_EQ( hv(tp), hv(a) );
146 }
147
148 {
149 std::tuple<int, int, int, int, int> tp( 1, 2, 3, 4, 5 );
150 int const a[] = { 1, 2, 3, 4, 5 };
151
152 BOOST_TEST_EQ( hv(tp), hv(a) );
153 }
154
155 {
156 std::tuple<int, int, int, int, int, int> tp( 1, 2, 3, 4, 5, 6 );
157 int const a[] = { 1, 2, 3, 4, 5, 6 };
158
159 BOOST_TEST_EQ( hv(tp), hv(a) );
160 }
161
162 {
163 std::tuple<int, int, int, int, int, int, int> tp( 1, 2, 3, 4, 5, 6, 7 );
164 int const a[] = { 1, 2, 3, 4, 5, 6, 7 };
165
166 BOOST_TEST_EQ( hv(tp), hv(a) );
167 }
168
169 {
170 std::tuple<int, int, int, int, int, int, int, int> tp( 1, 2, 3, 4, 5, 6, 7, 8 );
171 int const a[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
172
173 BOOST_TEST_EQ( hv(tp), hv(a) );
174 }
175
176 {
177 std::tuple<int, int, int, int, int, int, int, int, int> tp( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
178 int const a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
179
180 BOOST_TEST_EQ( hv(tp), hv(a) );
181 }
182
183#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1800)
184
185 {
186 user::Y1 tp = { .a: 1, .b: 2 };
187 int const a[] = { 1, 2 };
188
189 BOOST_TEST_EQ( hv(tp), hv(a) );
190 }
191
192#endif
193
194 {
195 user::Y2 tp = { .a: 1, .b: 2 };
196 int const a[] = { 1, 2 };
197
198 BOOST_TEST_EQ( hv(tp), hv(a) );
199 }
200
201#endif
202
203 return boost::report_errors();
204}
205

source code of boost/libs/container_hash/test/hash_tuple_like_test.cpp