]>
Commit | Line | Data |
---|---|---|
a945c346 | 1 | // Copyright (C) 2016-2024 Free Software Foundation, Inc. |
2dbe56bd JW |
2 | // |
3 | // This file is part of the GNU ISO C++ Library. This library is free | |
4 | // software; you can redistribute it and/or modify it under the | |
5 | // terms of the GNU General Public License as published by the | |
6 | // Free Software Foundation; either version 3, or (at your option) | |
7 | // any later version. | |
8 | ||
9 | // This library is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | ||
14 | // You should have received a copy of the GNU General Public License along | |
15 | // with this library; see the file COPYING3. If not see | |
16 | // <http://www.gnu.org/licenses/>. | |
17 | ||
6458742a | 18 | // { dg-do run { target c++17 } } |
2dbe56bd | 19 | |
c714b4d3 FD |
20 | #include <string> |
21 | #include <functional> | |
2dbe56bd JW |
22 | #include <unordered_map> |
23 | #include <algorithm> | |
24 | #include <testsuite_hooks.h> | |
25 | ||
26 | using test_type = std::unordered_map<int, int>; | |
27 | ||
c714b4d3 FD |
28 | template<typename T> |
29 | struct xhash | |
30 | { | |
31 | auto operator()(const T& i) const noexcept | |
32 | { return ~std::hash<T>()(i); } | |
33 | }; | |
34 | ||
35 | ||
36 | namespace std | |
37 | { | |
38 | template<typename T> | |
39 | struct __is_fast_hash<xhash<T>> : __is_fast_hash<std::hash<T>> | |
40 | { }; | |
41 | } | |
42 | ||
2dbe56bd JW |
43 | struct equal : std::equal_to<> { }; |
44 | ||
45 | template<typename C1, typename C2> | |
46 | bool equal_elements(const C1& c1, const C2& c2) | |
47 | { | |
48 | if (c2.size() != c1.size()) | |
49 | return false; | |
50 | for (auto& i : c1) | |
51 | if (c2.count(i.first) != c1.count(i.first)) | |
52 | return false; | |
53 | return true; | |
54 | } | |
55 | ||
56 | void | |
57 | test01() | |
58 | { | |
2dbe56bd JW |
59 | const test_type c0{ {1, 10}, {2, 20}, {3, 30} }; |
60 | test_type c1 = c0, c2 = c0; | |
61 | ||
62 | c1.merge(c2); | |
63 | VERIFY( c1 == c0 ); | |
64 | VERIFY( c2 == c0 ); | |
65 | ||
66 | c1.clear(); | |
67 | c1.merge(c2); | |
68 | VERIFY( c1 == c0 ); | |
69 | VERIFY( c2.empty() ); | |
70 | ||
71 | c2.merge(std::move(c1)); | |
72 | VERIFY( c1.empty() ); | |
73 | VERIFY( c2 == c0 ); | |
74 | } | |
75 | ||
76 | void | |
77 | test02() | |
78 | { | |
2dbe56bd JW |
79 | const test_type c0{ {1, 10}, {2, 20}, {3, 30} }; |
80 | test_type c1 = c0; | |
c714b4d3 | 81 | std::unordered_map<int, int, xhash<int>, equal> c2( c0.begin(), c0.end() ); |
2dbe56bd JW |
82 | |
83 | c1.merge(c2); | |
84 | VERIFY( c1 == c0 ); | |
85 | VERIFY( equal_elements(c2, c0) ); | |
86 | ||
87 | c1.clear(); | |
88 | c1.merge(c2); | |
89 | VERIFY( c1 == c0 ); | |
90 | VERIFY( c2.empty() ); | |
91 | ||
92 | c2.merge(c1); | |
93 | VERIFY( c1.empty() ); | |
94 | VERIFY( equal_elements(c2, c0) ); | |
95 | ||
96 | c1.merge(std::move(c2)); | |
97 | VERIFY( c2.empty() ); | |
98 | VERIFY( c1 == c0 ); | |
99 | } | |
100 | ||
101 | void | |
102 | test03() | |
103 | { | |
2dbe56bd JW |
104 | const test_type c0{ {1, 10}, {2, 20}, {3, 30} }; |
105 | test_type c1 = c0; | |
c714b4d3 | 106 | std::unordered_multimap<int, int, xhash<int>, equal> c2( c0.begin(), c0.end() ); |
2dbe56bd JW |
107 | c1.merge(c2); |
108 | VERIFY( c1 == c0 ); | |
109 | VERIFY( equal_elements(c2, c0) ); | |
110 | ||
111 | c1.clear(); | |
112 | c1.merge(c2); | |
113 | VERIFY( c1 == c0 ); | |
114 | VERIFY( c2.empty() ); | |
115 | ||
116 | c2.merge(c1); | |
117 | VERIFY( c1.empty() ); | |
118 | VERIFY( equal_elements(c2, c0) ); | |
119 | ||
120 | c1 = c0; | |
121 | c2.merge(c1); | |
122 | VERIFY( c1.empty() ); | |
123 | VERIFY( c2.size() == (2 * c0.size()) ); | |
124 | VERIFY( c2.count(1) == 2 ); | |
125 | VERIFY( c2.count(2) == 2 ); | |
126 | VERIFY( c2.count(3) == 2 ); | |
127 | ||
128 | c1.merge(c2); | |
129 | VERIFY( c1 == c0 ); | |
130 | VERIFY( equal_elements(c2, c0) ); | |
131 | ||
132 | c1.merge(std::move(c2)); | |
133 | VERIFY( c1 == c0 ); | |
134 | VERIFY( equal_elements(c2, c0) ); | |
135 | ||
136 | c1.clear(); | |
137 | c1.merge(std::move(c2)); | |
138 | VERIFY( c1 == c0 ); | |
139 | VERIFY( c2.empty() ); | |
140 | } | |
141 | ||
c714b4d3 FD |
142 | void |
143 | test04() | |
144 | { | |
145 | const std::unordered_map<std::string, int> c0 | |
146 | { {"one", 10}, {"two", 20}, {"three", 30} }; | |
147 | ||
148 | std::unordered_map<std::string, int> c1 = c0; | |
149 | std::unordered_multimap<std::string, int> c2( c0.begin(), c0.end() ); | |
150 | c1.merge(c2); | |
151 | VERIFY( c1 == c0 ); | |
152 | VERIFY( equal_elements(c2, c0) ); | |
153 | ||
154 | c1.clear(); | |
155 | c1.merge(c2); | |
156 | VERIFY( c1 == c0 ); | |
157 | VERIFY( c2.empty() ); | |
158 | ||
159 | c2.merge(c1); | |
160 | VERIFY( c1.empty() ); | |
161 | VERIFY( equal_elements(c2, c0) ); | |
162 | ||
163 | c1 = c0; | |
164 | c2.merge(c1); | |
165 | VERIFY( c1.empty() ); | |
166 | VERIFY( c2.size() == (2 * c0.size()) ); | |
167 | VERIFY( c2.count("one") == 2 ); | |
168 | VERIFY( c2.count("two") == 2 ); | |
169 | VERIFY( c2.count("three") == 2 ); | |
170 | ||
171 | c1.merge(c2); | |
172 | VERIFY( c1 == c0 ); | |
173 | VERIFY( equal_elements(c2, c0) ); | |
174 | ||
175 | c1.merge(std::move(c2)); | |
176 | VERIFY( c1 == c0 ); | |
177 | VERIFY( equal_elements(c2, c0) ); | |
178 | ||
179 | c1.clear(); | |
180 | c1.merge(std::move(c2)); | |
181 | VERIFY( c1 == c0 ); | |
182 | VERIFY( c2.empty() ); | |
183 | } | |
184 | ||
185 | void | |
186 | test05() | |
187 | { | |
188 | const std::unordered_map<std::string, int> c0 | |
189 | { {"one", 10}, {"two", 20}, {"three", 30} }; | |
190 | ||
191 | std::unordered_map<std::string, int> c1 = c0; | |
192 | std::unordered_multimap<std::string, int, xhash<std::string>, equal> c2( c0.begin(), c0.end() ); | |
193 | c1.merge(c2); | |
194 | VERIFY( c1 == c0 ); | |
195 | VERIFY( equal_elements(c2, c0) ); | |
196 | ||
197 | c1.clear(); | |
198 | c1.merge(c2); | |
199 | VERIFY( c1 == c0 ); | |
200 | VERIFY( c2.empty() ); | |
201 | ||
202 | c2.merge(c1); | |
203 | VERIFY( c1.empty() ); | |
204 | VERIFY( equal_elements(c2, c0) ); | |
205 | ||
206 | c1 = c0; | |
207 | c2.merge(c1); | |
208 | VERIFY( c1.empty() ); | |
209 | VERIFY( c2.size() == (2 * c0.size()) ); | |
210 | VERIFY( c2.count("one") == 2 ); | |
211 | VERIFY( c2.count("two") == 2 ); | |
212 | VERIFY( c2.count("three") == 2 ); | |
213 | ||
214 | c1.merge(c2); | |
215 | VERIFY( c1 == c0 ); | |
216 | VERIFY( equal_elements(c2, c0) ); | |
217 | ||
218 | c1.merge(std::move(c2)); | |
219 | VERIFY( c1 == c0 ); | |
220 | VERIFY( equal_elements(c2, c0) ); | |
221 | ||
222 | c1.clear(); | |
223 | c1.merge(std::move(c2)); | |
224 | VERIFY( c1 == c0 ); | |
225 | VERIFY( c2.empty() ); | |
226 | } | |
227 | ||
228 | template<typename T> | |
229 | using hash_f = | |
230 | std::function<std::size_t(const T&)>; | |
231 | ||
232 | std::size_t | |
233 | hash_func(const std::string& str) | |
234 | { return std::hash<std::string>{}(str); } | |
235 | ||
236 | std::size_t | |
237 | xhash_func(const std::string& str) | |
238 | { return xhash<std::string>{}(str); } | |
239 | ||
240 | namespace std | |
241 | { | |
242 | template<typename T> | |
243 | struct __is_fast_hash<hash_f<T>> : __is_fast_hash<std::hash<T>> | |
244 | { }; | |
245 | } | |
246 | ||
247 | void | |
248 | test06() | |
249 | { | |
250 | const std::unordered_map<std::string, int, hash_f<std::string>, equal> | |
251 | c0({ {"one", 10}, {"two", 20}, {"three", 30} }, 3, &hash_func); | |
252 | ||
253 | std::unordered_map<std::string, int, hash_f<std::string>, equal> | |
254 | c1(3, &hash_func); | |
255 | c1 = c0; | |
256 | std::unordered_multimap<std::string, int, hash_f<std::string>, equal> | |
257 | c2(c0.begin(), c0.end(), 3, &xhash_func); | |
258 | c1.merge(c2); | |
259 | VERIFY( c1 == c0 ); | |
260 | VERIFY( equal_elements(c2, c0) ); | |
261 | ||
262 | c1.clear(); | |
263 | c1.merge(c2); | |
264 | VERIFY( c1 == c0 ); | |
265 | VERIFY( c2.empty() ); | |
266 | ||
267 | c2.merge(c1); | |
268 | VERIFY( c1.empty() ); | |
269 | VERIFY( equal_elements(c2, c0) ); | |
270 | ||
271 | c1 = c0; | |
272 | c2.merge(c1); | |
273 | VERIFY( c1.empty() ); | |
274 | VERIFY( c2.size() == (2 * c0.size()) ); | |
275 | VERIFY( c2.count("one") == 2 ); | |
276 | VERIFY( c2.count("two") == 2 ); | |
277 | VERIFY( c2.count("three") == 2 ); | |
278 | ||
279 | c1.merge(c2); | |
280 | VERIFY( c1 == c0 ); | |
281 | VERIFY( equal_elements(c2, c0) ); | |
282 | ||
283 | c1.merge(std::move(c2)); | |
284 | VERIFY( c1 == c0 ); | |
285 | VERIFY( equal_elements(c2, c0) ); | |
286 | ||
287 | c1.clear(); | |
288 | c1.merge(std::move(c2)); | |
289 | VERIFY( c1 == c0 ); | |
290 | VERIFY( c2.empty() ); | |
291 | } | |
292 | ||
2dbe56bd JW |
293 | int |
294 | main() | |
295 | { | |
296 | test01(); | |
297 | test02(); | |
298 | test03(); | |
c714b4d3 FD |
299 | test04(); |
300 | test05(); | |
301 | test06(); | |
2dbe56bd | 302 | } |