1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <unordered_map>
11
12// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
13//           class Alloc = allocator<pair<const Key, T>>>
14// class unordered_multimap
15
16// unordered_multimap& operator=(unordered_multimap&& u);
17
18#include <unordered_map>
19#include <string>
20#include <cassert>
21#include <cfloat>
22#include <cstddef>
23
24#include "test_macros.h"
25#include "../../../test_compare.h"
26#include "../../../test_hash.h"
27#include "test_allocator.h"
28#include "min_allocator.h"
29
30int main()
31{
32#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
33    {
34        typedef test_allocator<std::pair<const int, std::string> > A;
35        typedef std::unordered_multimap<int, std::string,
36                                   test_hash<std::hash<int> >,
37                                   test_compare<std::equal_to<int> >,
38                                   A
39                                   > C;
40        typedef std::pair<int, std::string> P;
41        P a[] =
42        {
43            P(1, "one"),
44            P(2, "two"),
45            P(3, "three"),
46            P(4, "four"),
47            P(1, "four"),
48            P(2, "four"),
49        };
50        C c0(a, a + sizeof(a)/sizeof(a[0]),
51            7,
52            test_hash<std::hash<int> >(8),
53            test_compare<std::equal_to<int> >(9),
54            A(10)
55           );
56        C c(a, a + 2,
57            7,
58            test_hash<std::hash<int> >(2),
59            test_compare<std::equal_to<int> >(3),
60            A(4)
61           );
62        c = std::move(c0);
63        LIBCPP_ASSERT(c.bucket_count() == 7);
64        assert(c.size() == 6);
65        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
66        Eq eq = c.equal_range(1);
67        assert(std::distance(eq.first, eq.second) == 2);
68        C::const_iterator i = eq.first;
69        assert(i->first == 1);
70        assert(i->second == "one");
71        ++i;
72        assert(i->first == 1);
73        assert(i->second == "four");
74        eq = c.equal_range(2);
75        assert(std::distance(eq.first, eq.second) == 2);
76        i = eq.first;
77        assert(i->first == 2);
78        assert(i->second == "two");
79        ++i;
80        assert(i->first == 2);
81        assert(i->second == "four");
82
83        eq = c.equal_range(3);
84        assert(std::distance(eq.first, eq.second) == 1);
85        i = eq.first;
86        assert(i->first == 3);
87        assert(i->second == "three");
88        eq = c.equal_range(4);
89        assert(std::distance(eq.first, eq.second) == 1);
90        i = eq.first;
91        assert(i->first == 4);
92        assert(i->second == "four");
93        assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
94        assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
95        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
96        assert(c.max_load_factor() == 1);
97    }
98    {
99        typedef test_allocator<std::pair<const int, std::string> > A;
100        typedef std::unordered_multimap<int, std::string,
101                                   test_hash<std::hash<int> >,
102                                   test_compare<std::equal_to<int> >,
103                                   A
104                                   > C;
105        typedef std::pair<int, std::string> P;
106        P a[] =
107        {
108            P(1, "one"),
109            P(2, "two"),
110            P(3, "three"),
111            P(4, "four"),
112            P(1, "four"),
113            P(2, "four"),
114        };
115        C c0(a, a + sizeof(a)/sizeof(a[0]),
116            7,
117            test_hash<std::hash<int> >(8),
118            test_compare<std::equal_to<int> >(9),
119            A(10)
120           );
121        C c(a, a + 2,
122            7,
123            test_hash<std::hash<int> >(2),
124            test_compare<std::equal_to<int> >(3),
125            A(10)
126           );
127        c = std::move(c0);
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        C::const_iterator i = eq.first;
134        assert(i->first == 1);
135        assert(i->second == "one");
136        ++i;
137        assert(i->first == 1);
138        assert(i->second == "four");
139        eq = c.equal_range(2);
140        assert(std::distance(eq.first, eq.second) == 2);
141        i = eq.first;
142        assert(i->first == 2);
143        assert(i->second == "two");
144        ++i;
145        assert(i->first == 2);
146        assert(i->second == "four");
147
148        eq = c.equal_range(3);
149        assert(std::distance(eq.first, eq.second) == 1);
150        i = eq.first;
151        assert(i->first == 3);
152        assert(i->second == "three");
153        eq = c.equal_range(4);
154        assert(std::distance(eq.first, eq.second) == 1);
155        i = eq.first;
156        assert(i->first == 4);
157        assert(i->second == "four");
158        assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
159        assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
160        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
161        assert(c.max_load_factor() == 1);
162    }
163    {
164        typedef other_allocator<std::pair<const int, std::string> > A;
165        typedef std::unordered_multimap<int, std::string,
166                                   test_hash<std::hash<int> >,
167                                   test_compare<std::equal_to<int> >,
168                                   A
169                                   > C;
170        typedef std::pair<int, std::string> P;
171        P a[] =
172        {
173            P(1, "one"),
174            P(2, "two"),
175            P(3, "three"),
176            P(4, "four"),
177            P(1, "four"),
178            P(2, "four"),
179        };
180        C c0(a, a + sizeof(a)/sizeof(a[0]),
181            7,
182            test_hash<std::hash<int> >(8),
183            test_compare<std::equal_to<int> >(9),
184            A(10)
185           );
186        C c(a, a + 2,
187            7,
188            test_hash<std::hash<int> >(2),
189            test_compare<std::equal_to<int> >(3),
190            A(4)
191           );
192        c = std::move(c0);
193        LIBCPP_ASSERT(c.bucket_count() == 7);
194        assert(c.size() == 6);
195        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
196        Eq eq = c.equal_range(1);
197        assert(std::distance(eq.first, eq.second) == 2);
198        C::const_iterator i = eq.first;
199        assert(i->first == 1);
200        assert(i->second == "one");
201        ++i;
202        assert(i->first == 1);
203        assert(i->second == "four");
204        eq = c.equal_range(2);
205        assert(std::distance(eq.first, eq.second) == 2);
206        i = eq.first;
207        assert(i->first == 2);
208        assert(i->second == "two");
209        ++i;
210        assert(i->first == 2);
211        assert(i->second == "four");
212
213        eq = c.equal_range(3);
214        assert(std::distance(eq.first, eq.second) == 1);
215        i = eq.first;
216        assert(i->first == 3);
217        assert(i->second == "three");
218        eq = c.equal_range(4);
219        assert(std::distance(eq.first, eq.second) == 1);
220        i = eq.first;
221        assert(i->first == 4);
222        assert(i->second == "four");
223        assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
224        assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
225        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
226        assert(c.max_load_factor() == 1);
227    }
228#if TEST_STD_VER >= 11
229    {
230        typedef min_allocator<std::pair<const int, std::string> > A;
231        typedef std::unordered_multimap<int, std::string,
232                                   test_hash<std::hash<int> >,
233                                   test_compare<std::equal_to<int> >,
234                                   A
235                                   > C;
236        typedef std::pair<int, std::string> P;
237        P a[] =
238        {
239            P(1, "one"),
240            P(2, "two"),
241            P(3, "three"),
242            P(4, "four"),
243            P(1, "four"),
244            P(2, "four"),
245        };
246        C c0(a, a + sizeof(a)/sizeof(a[0]),
247            7,
248            test_hash<std::hash<int> >(8),
249            test_compare<std::equal_to<int> >(9),
250            A()
251           );
252        C c(a, a + 2,
253            7,
254            test_hash<std::hash<int> >(2),
255            test_compare<std::equal_to<int> >(3),
256            A()
257           );
258        c = std::move(c0);
259        LIBCPP_ASSERT(c.bucket_count() == 7);
260        assert(c.size() == 6);
261        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
262        Eq eq = c.equal_range(1);
263        assert(std::distance(eq.first, eq.second) == 2);
264        C::const_iterator i = eq.first;
265        assert(i->first == 1);
266        assert(i->second == "one");
267        ++i;
268        assert(i->first == 1);
269        assert(i->second == "four");
270        eq = c.equal_range(2);
271        assert(std::distance(eq.first, eq.second) == 2);
272        i = eq.first;
273        assert(i->first == 2);
274        assert(i->second == "two");
275        ++i;
276        assert(i->first == 2);
277        assert(i->second == "four");
278
279        eq = c.equal_range(3);
280        assert(std::distance(eq.first, eq.second) == 1);
281        i = eq.first;
282        assert(i->first == 3);
283        assert(i->second == "three");
284        eq = c.equal_range(4);
285        assert(std::distance(eq.first, eq.second) == 1);
286        i = eq.first;
287        assert(i->first == 4);
288        assert(i->second == "four");
289        assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
290        assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
291        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
292        assert(c.max_load_factor() == 1);
293    }
294#endif
295#if _LIBCPP_DEBUG >= 1
296    {
297        std::unordered_multimap<int, int> s1 = {{1, 1}, {2, 2}, {3, 3}};
298        std::unordered_multimap<int, int>::iterator i = s1.begin();
299        std::pair<const int, int> k = *i;
300        std::unordered_multimap<int, int> s2;
301        s2 = std::move(s1);
302        assert(*i == k);
303        s2.erase(i);
304        assert(s2.size() == 2);
305    }
306#endif
307#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
308}
309