1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03
10 
11 // <unordered_map>
12 
13 // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
14 //           class Alloc = allocator<pair<const Key, T>>>
15 // class unordered_multimap
16 
17 // unordered_multimap& operator=(unordered_multimap&& u);
18 
19 #include <unordered_map>
20 #include <string>
21 #include <set>
22 #include <cassert>
23 #include <cfloat>
24 #include <cmath>
25 #include <cstddef>
26 
27 #include "test_macros.h"
28 #include "../../../check_consecutive.h"
29 #include "../../../test_compare.h"
30 #include "../../../test_hash.h"
31 #include "test_allocator.h"
32 #include "min_allocator.h"
33 
main(int,char **)34 int main(int, char**)
35 {
36     {
37         typedef test_allocator<std::pair<const int, std::string> > A;
38         typedef std::unordered_multimap<int, std::string,
39                                    test_hash<int>,
40                                    test_equal_to<int>,
41                                    A
42                                    > C;
43         typedef std::pair<int, std::string> P;
44         P a[] =
45         {
46             P(1, "one"),
47             P(2, "two"),
48             P(3, "three"),
49             P(4, "four"),
50             P(1, "four"),
51             P(2, "four"),
52         };
53         C c0(a, a + sizeof(a)/sizeof(a[0]),
54             7,
55             test_hash<int>(8),
56             test_equal_to<int>(9),
57             A(10)
58            );
59         C c(a, a + 2,
60             7,
61             test_hash<int>(2),
62             test_equal_to<int>(3),
63             A(4)
64            );
65         c = std::move(c0);
66         LIBCPP_ASSERT(c.bucket_count() == 7);
67         assert(c.size() == 6);
68         typedef std::pair<C::const_iterator, C::const_iterator> Eq;
69         Eq eq = c.equal_range(1);
70         assert(std::distance(eq.first, eq.second) == 2);
71         std::multiset<std::string> s;
72         s.insert("one");
73         s.insert("four");
74         CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
75         eq = c.equal_range(2);
76         assert(std::distance(eq.first, eq.second) == 2);
77         s.insert("two");
78         s.insert("four");
79         CheckConsecutiveKeys<C::const_iterator>(c.find(2), c.end(), 2, s);
80 
81         eq = c.equal_range(3);
82         assert(std::distance(eq.first, eq.second) == 1);
83         C::const_iterator i = eq.first;
84         assert(i->first == 3);
85         assert(i->second == "three");
86         eq = c.equal_range(4);
87         assert(std::distance(eq.first, eq.second) == 1);
88         i = eq.first;
89         assert(i->first == 4);
90         assert(i->second == "four");
91         assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
92         assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
93         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
94         assert(c.max_load_factor() == 1);
95     }
96     {
97         typedef test_allocator<std::pair<const int, std::string> > A;
98         typedef std::unordered_multimap<int, std::string,
99                                    test_hash<int>,
100                                    test_equal_to<int>,
101                                    A
102                                    > C;
103         typedef std::pair<int, std::string> P;
104         P a[] =
105         {
106             P(1, "one"),
107             P(2, "two"),
108             P(3, "three"),
109             P(4, "four"),
110             P(1, "four"),
111             P(2, "four"),
112         };
113         C c0(a, a + sizeof(a)/sizeof(a[0]),
114             7,
115             test_hash<int>(8),
116             test_equal_to<int>(9),
117             A(10)
118            );
119         C c(a, a + 2,
120             7,
121             test_hash<int>(2),
122             test_equal_to<int>(3),
123             A(10)
124            );
125         C::iterator it0 = c0.begin();
126         c = std::move(c0);
127         assert(it0 == c.begin()); // Iterators remain valid
128         LIBCPP_ASSERT(c.bucket_count() == 7);
129         assert(c.size() == 6);
130         typedef std::pair<C::const_iterator, C::const_iterator> Eq;
131         Eq eq = c.equal_range(1);
132         assert(std::distance(eq.first, eq.second) == 2);
133         std::multiset<std::string> s;
134         s.insert("one");
135         s.insert("four");
136         CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
137         eq = c.equal_range(2);
138         assert(std::distance(eq.first, eq.second) == 2);
139         s.insert("two");
140         s.insert("four");
141         CheckConsecutiveKeys<C::const_iterator>(c.find(2), c.end(), 2, s);
142 
143         eq = c.equal_range(3);
144         assert(std::distance(eq.first, eq.second) == 1);
145         C::const_iterator i = eq.first;
146         assert(i->first == 3);
147         assert(i->second == "three");
148         eq = c.equal_range(4);
149         assert(std::distance(eq.first, eq.second) == 1);
150         i = eq.first;
151         assert(i->first == 4);
152         assert(i->second == "four");
153         assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
154         assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
155         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
156         assert(c.max_load_factor() == 1);
157     }
158     {
159         typedef other_allocator<std::pair<const int, std::string> > A;
160         typedef std::unordered_multimap<int, std::string,
161                                    test_hash<int>,
162                                    test_equal_to<int>,
163                                    A
164                                    > C;
165         typedef std::pair<int, std::string> P;
166         P a[] =
167         {
168             P(1, "one"),
169             P(2, "two"),
170             P(3, "three"),
171             P(4, "four"),
172             P(1, "four"),
173             P(2, "four"),
174         };
175         C c0(a, a + sizeof(a)/sizeof(a[0]),
176             7,
177             test_hash<int>(8),
178             test_equal_to<int>(9),
179             A(10)
180            );
181         C c(a, a + 2,
182             7,
183             test_hash<int>(2),
184             test_equal_to<int>(3),
185             A(4)
186            );
187         C::iterator it0 = c0.begin();
188         c = std::move(c0);
189         assert(it0 == c.begin()); // Iterators remain valid
190         LIBCPP_ASSERT(c.bucket_count() == 7);
191         assert(c.size() == 6);
192         typedef std::pair<C::const_iterator, C::const_iterator> Eq;
193         Eq eq = c.equal_range(1);
194         assert(std::distance(eq.first, eq.second) == 2);
195         std::multiset<std::string> s;
196         s.insert("one");
197         s.insert("four");
198         CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
199         eq = c.equal_range(2);
200         assert(std::distance(eq.first, eq.second) == 2);
201         s.insert("two");
202         s.insert("four");
203         CheckConsecutiveKeys<C::const_iterator>(c.find(2), c.end(), 2, s);
204 
205         eq = c.equal_range(3);
206         assert(std::distance(eq.first, eq.second) == 1);
207         C::const_iterator i = eq.first;
208         assert(i->first == 3);
209         assert(i->second == "three");
210         eq = c.equal_range(4);
211         assert(std::distance(eq.first, eq.second) == 1);
212         i = eq.first;
213         assert(i->first == 4);
214         assert(i->second == "four");
215         assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
216         assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
217         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
218         assert(c.max_load_factor() == 1);
219     }
220     {
221         typedef min_allocator<std::pair<const int, std::string> > A;
222         typedef std::unordered_multimap<int, std::string,
223                                    test_hash<int>,
224                                    test_equal_to<int>,
225                                    A
226                                    > C;
227         typedef std::pair<int, std::string> P;
228         P a[] =
229         {
230             P(1, "one"),
231             P(2, "two"),
232             P(3, "three"),
233             P(4, "four"),
234             P(1, "four"),
235             P(2, "four"),
236         };
237         C c0(a, a + sizeof(a)/sizeof(a[0]),
238             7,
239             test_hash<int>(8),
240             test_equal_to<int>(9),
241             A()
242            );
243         C c(a, a + 2,
244             7,
245             test_hash<int>(2),
246             test_equal_to<int>(3),
247             A()
248            );
249         C::iterator it0 = c0.begin();
250         c = std::move(c0);
251         assert(it0 == c.begin()); // Iterators remain valid
252         LIBCPP_ASSERT(c.bucket_count() == 7);
253         assert(c.size() == 6);
254         typedef std::pair<C::const_iterator, C::const_iterator> Eq;
255         Eq eq = c.equal_range(1);
256         assert(std::distance(eq.first, eq.second) == 2);
257         std::multiset<std::string> s;
258         s.insert("one");
259         s.insert("four");
260         CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
261         eq = c.equal_range(2);
262         assert(std::distance(eq.first, eq.second) == 2);
263         s.insert("two");
264         s.insert("four");
265         CheckConsecutiveKeys<C::const_iterator>(c.find(2), c.end(), 2, s);
266 
267         eq = c.equal_range(3);
268         assert(std::distance(eq.first, eq.second) == 1);
269         C::const_iterator i = eq.first;
270         assert(i->first == 3);
271         assert(i->second == "three");
272         eq = c.equal_range(4);
273         assert(std::distance(eq.first, eq.second) == 1);
274         i = eq.first;
275         assert(i->first == 4);
276         assert(i->second == "four");
277         assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
278         assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
279         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
280         assert(c.max_load_factor() == 1);
281     }
282 
283   return 0;
284 }
285