1
2// Copyright 2006-2009 Daniel James.
3// Copyright 2022-2023 Christian Mazakas.
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7// This test creates the containers with members that meet their minimum
8// requirements. Makes sure everything compiles and is defined correctly.
9
10#include "../helpers/unordered.hpp"
11
12#include "../helpers/test.hpp"
13#include "../objects/minimal.hpp"
14#include "./compile_tests.hpp"
15
16// Explicit instantiation to catch compile-time errors
17#ifdef BOOST_UNORDERED_FOA_TESTS
18
19// emulates what was already done for previous tests but without leaking to
20// the detail namespace
21//
22template <typename K, typename T, typename H, typename P, typename A>
23class instantiate_flat_map
24{
25 typedef boost::unordered_flat_map<K, T, H, P, A> container;
26 container x;
27};
28
29template class instantiate_flat_map<int, int, boost::hash<int>,
30 std::equal_to<int>, test::minimal::allocator<int> >;
31
32template class instantiate_flat_map<test::minimal::assignable const,
33 test::minimal::default_assignable const,
34 test::minimal::hash<test::minimal::assignable>,
35 test::minimal::equal_to<test::minimal::assignable>,
36 test::minimal::allocator<int> >;
37
38template <typename K, typename T, typename H, typename P, typename A>
39class instantiate_node_map
40{
41 typedef boost::unordered_node_map<K, T, H, P, A> container;
42 container x;
43};
44
45template class instantiate_node_map<int, int, boost::hash<int>,
46 std::equal_to<int>, test::minimal::allocator<int> >;
47
48template class instantiate_node_map<test::minimal::assignable const,
49 test::minimal::default_assignable const,
50 test::minimal::hash<test::minimal::assignable>,
51 test::minimal::equal_to<test::minimal::assignable>,
52 test::minimal::allocator<int> >;
53
54#else
55#define INSTANTIATE(type) \
56 template class boost::unordered::detail::instantiate_##type
57
58INSTANTIATE(map)<int, int, boost::hash<int>, std::equal_to<int>,
59 test::minimal::allocator<int> >;
60INSTANTIATE(multimap)<int const, int const, boost::hash<int>,
61 std::equal_to<int>, test::minimal::allocator<int> >;
62
63INSTANTIATE(
64 map)<test::minimal::assignable const, test::minimal::default_assignable const,
65 test::minimal::hash<test::minimal::assignable>,
66 test::minimal::equal_to<test::minimal::assignable>,
67 test::minimal::allocator<int> >;
68INSTANTIATE(multimap)<test::minimal::assignable, test::minimal::assignable,
69 test::minimal::hash<test::minimal::assignable>,
70 test::minimal::equal_to<test::minimal::assignable>,
71 test::minimal::allocator<int> >;
72#endif
73
74template <template <class Key, class T, class H = boost::hash<Key>,
75 class P = std::equal_to<Key>,
76 class Allocator = std::allocator<std::pair<Key const, T> > >
77 class Map>
78static void test0_impl()
79{
80 test::minimal::constructor_param x;
81
82 typedef std::pair<test::minimal::assignable const, test::minimal::assignable>
83 value_type;
84 value_type value(x, x);
85
86 Map<int, int> int_map;
87
88 Map<int, int, boost::hash<int>, std::equal_to<int>,
89 test::minimal::cxx11_allocator<std::pair<int const, int> > >
90 int_map2;
91
92 Map<test::minimal::assignable, test::minimal::assignable,
93 test::minimal::hash<test::minimal::assignable>,
94 test::minimal::equal_to<test::minimal::assignable>,
95 test::minimal::allocator<value_type> >
96 map;
97
98 container_test(int_map, std::pair<int const, int>(0, 0));
99 container_test(int_map2, std::pair<int const, int>(0, 0));
100 container_test(map, value);
101}
102
103UNORDERED_AUTO_TEST (test0) {
104#ifdef BOOST_UNORDERED_FOA_TESTS
105 test0_impl<boost::unordered_flat_map>();
106 test0_impl<boost::unordered_node_map>();
107#else
108 test0_impl<boost::unordered_map>();
109 test0_impl<boost::unordered_multimap>();
110#endif
111}
112
113template <template <class Key, class T, class H = boost::hash<Key>,
114 class P = std::equal_to<Key>,
115 class Allocator = std::allocator<std::pair<Key const, T> > >
116 class Map>
117static void equality_tests_impl()
118{
119 typedef std::pair<test::minimal::copy_constructible_equality_comparable const,
120 test::minimal::copy_constructible_equality_comparable>
121 value_type;
122
123 Map<int, int> int_map;
124
125 Map<int, int, boost::hash<int>, std::equal_to<int>,
126 test::minimal::cxx11_allocator<std::pair<int const, int> > >
127 int_map2;
128
129 Map<test::minimal::copy_constructible_equality_comparable,
130 test::minimal::copy_constructible_equality_comparable,
131 test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
132 test::minimal::equal_to<
133 test::minimal::copy_constructible_equality_comparable>,
134 test::minimal::allocator<value_type> >
135 map;
136
137 equality_test(int_map);
138 equality_test(int_map2);
139 equality_test(map);
140}
141
142UNORDERED_AUTO_TEST (equality_tests) {
143#ifdef BOOST_UNORDERED_FOA_TESTS
144 equality_tests_impl<boost::unordered_flat_map>();
145 equality_tests_impl<boost::unordered_node_map>();
146#else
147 equality_tests_impl<boost::unordered_map>();
148 equality_tests_impl<boost::unordered_multimap>();
149#endif
150}
151
152template <template <class Key, class T, class H = boost::hash<Key>,
153 class P = std::equal_to<Key>,
154 class Allocator = std::allocator<std::pair<Key const, T> > >
155 class Map>
156static void test1_unique_impl()
157{
158
159 boost::hash<int> hash;
160 std::equal_to<int> equal_to;
161 int value = 0;
162 std::pair<int const, int> map_value(0, 0);
163
164 Map<int, int> map;
165
166 Map<int, int, boost::hash<int>, std::equal_to<int>,
167 test::minimal::cxx11_allocator<std::pair<int const, int> > >
168 map2;
169
170 unordered_unique_test(map, map_value);
171 unordered_map_test(map, value, value);
172 unordered_copyable_test(map, value, map_value, hash, equal_to);
173 unordered_map_functions(map, value, value);
174
175 unordered_unique_test(map2, map_value);
176 unordered_map_test(map2, value, value);
177 unordered_copyable_test(map2, value, map_value, hash, equal_to);
178 unordered_map_functions(map2, value, value);
179}
180
181#ifndef BOOST_UNORDERED_FOA_TESTS
182template <template <class Key, class T, class H = boost::hash<Key>,
183 class P = std::equal_to<Key>,
184 class Allocator = std::allocator<std::pair<Key const, T> > >
185 class Map>
186static void test1_equivalent_impl()
187{
188
189 boost::hash<int> hash;
190 std::equal_to<int> equal_to;
191 int value = 0;
192 std::pair<int const, int> map_value(0, 0);
193
194 Map<int, int> map;
195
196 Map<int, int, boost::hash<int>, std::equal_to<int>,
197 test::minimal::cxx11_allocator<std::pair<int const, int> > >
198 map2;
199
200 unordered_equivalent_test(map, map_value);
201 unordered_map_test(map, value, value);
202 unordered_copyable_test(map, value, map_value, hash, equal_to);
203
204 unordered_equivalent_test(map2, map_value);
205 unordered_map_test(map2, value, value);
206 unordered_copyable_test(map2, value, map_value, hash, equal_to);
207}
208#endif
209
210UNORDERED_AUTO_TEST (test1) {
211#ifdef BOOST_UNORDERED_FOA_TESTS
212 test1_unique_impl<boost::unordered_flat_map>();
213 test1_unique_impl<boost::unordered_node_map>();
214#else
215 test1_unique_impl<boost::unordered_map>();
216 test1_equivalent_impl<boost::unordered_multimap>();
217#endif
218}
219
220template <template <class Key, class T, class H = boost::hash<Key>,
221 class P = std::equal_to<Key>,
222 class Allocator = std::allocator<std::pair<Key const, T> > >
223 class Map>
224static void test2_unique_impl()
225{
226 test::minimal::constructor_param x;
227
228 test::minimal::assignable assignable(x);
229 test::minimal::copy_constructible copy_constructible(x);
230 test::minimal::hash<test::minimal::assignable> hash(x);
231 test::minimal::equal_to<test::minimal::assignable> equal_to(x);
232
233 typedef std::pair<test::minimal::assignable const, test::minimal::assignable>
234 map_value_type;
235 map_value_type map_value(assignable, assignable);
236
237 Map<test::minimal::assignable, test::minimal::assignable,
238 test::minimal::hash<test::minimal::assignable>,
239 test::minimal::equal_to<test::minimal::assignable>,
240 test::minimal::allocator<map_value_type> >
241 map;
242
243 unordered_unique_test(map, map_value);
244 unordered_map_test(map, assignable, assignable);
245 unordered_copyable_test(map, assignable, map_value, hash, equal_to);
246 unordered_map_member_test(map, map_value);
247
248 Map<test::minimal::assignable, test::minimal::default_assignable,
249 test::minimal::hash<test::minimal::assignable>,
250 test::minimal::equal_to<test::minimal::assignable>,
251 test::minimal::allocator<map_value_type> >
252 map2;
253
254 test::minimal::default_assignable default_assignable;
255
256 unordered_map_functions(map2, assignable, default_assignable);
257}
258
259#ifndef BOOST_UNORDERED_FOA_TESTS
260template <template <class Key, class T, class H = boost::hash<Key>,
261 class P = std::equal_to<Key>,
262 class Allocator = std::allocator<std::pair<Key const, T> > >
263 class Map>
264static void test2_equivalent_impl()
265{
266 test::minimal::constructor_param x;
267
268 test::minimal::assignable assignable(x);
269 test::minimal::copy_constructible copy_constructible(x);
270 test::minimal::hash<test::minimal::assignable> hash(x);
271 test::minimal::equal_to<test::minimal::assignable> equal_to(x);
272
273 typedef std::pair<test::minimal::assignable const, test::minimal::assignable>
274 map_value_type;
275 map_value_type map_value(assignable, assignable);
276
277 Map<test::minimal::assignable, test::minimal::assignable,
278 test::minimal::hash<test::minimal::assignable>,
279 test::minimal::equal_to<test::minimal::assignable>,
280 test::minimal::allocator<map_value_type> >
281 map;
282
283 unordered_equivalent_test(map, map_value);
284 unordered_map_test(map, assignable, assignable);
285 unordered_copyable_test(map, assignable, map_value, hash, equal_to);
286 unordered_map_member_test(map, map_value);
287}
288#endif
289
290UNORDERED_AUTO_TEST (test2) {
291#ifdef BOOST_UNORDERED_FOA_TESTS
292 test2_unique_impl<boost::unordered_flat_map>();
293 test2_unique_impl<boost::unordered_node_map>();
294#else
295 test2_unique_impl<boost::unordered_map>();
296 test2_equivalent_impl<boost::unordered_multimap>();
297#endif
298}
299
300// Test for ambiguity when using key convertible from iterator
301// See LWG2059
302
303struct lwg2059_key
304{
305 int value;
306
307 template <typename T> lwg2059_key(T v) : value(v) {}
308};
309
310std::size_t hash_value(lwg2059_key x)
311{
312 return static_cast<std::size_t>(x.value);
313}
314
315bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
316
317UNORDERED_AUTO_TEST (lwg2059) {
318#ifdef BOOST_UNORDERED_FOA_TESTS
319 {
320 boost::unordered_flat_map<lwg2059_key, int> x;
321 x.emplace(lwg2059_key(10), 5);
322 x.erase(x.begin());
323 }
324
325 {
326 boost::unordered_node_map<lwg2059_key, int> x;
327 x.emplace(lwg2059_key(10), 5);
328 x.erase(x.begin());
329 }
330#else
331 {
332 boost::unordered_map<lwg2059_key, int> x;
333 x.emplace(args: lwg2059_key(10), args: 5);
334 x.erase(position: x.begin());
335 }
336
337 {
338 boost::unordered_multimap<lwg2059_key, int> x;
339 x.emplace(args: lwg2059_key(10), args: 5);
340 x.erase(position: x.begin());
341 }
342#endif
343}
344
345RUN_TESTS()
346

source code of boost/libs/unordered/test/unordered/compile_map.cpp