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
23#include "../../../test_compare.h"
24#include "../../../test_hash.h"
25#include "test_allocator.h"
26#include "min_allocator.h"
27
28int main()
29{
30#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
31    {
32        typedef test_allocator<std::pair<const int, std::string> > A;
33        typedef std::unordered_multimap<int, std::string,
34                                   test_hash<std::hash<int> >,
35                                   test_compare<std::equal_to<int> >,
36                                   A
37                                   > C;
38        typedef std::pair<int, std::string> P;
39        P a[] =
40        {
41            P(1, "one"),
42            P(2, "two"),
43            P(3, "three"),
44            P(4, "four"),
45            P(1, "four"),
46            P(2, "four"),
47        };
48        C c0(a, a + sizeof(a)/sizeof(a[0]),
49            7,
50            test_hash<std::hash<int> >(8),
51            test_compare<std::equal_to<int> >(9),
52            A(10)
53           );
54        C c(a, a + 2,
55            7,
56            test_hash<std::hash<int> >(2),
57            test_compare<std::equal_to<int> >(3),
58            A(4)
59           );
60        c = std::move(c0);
61        assert(c.bucket_count() == 7);
62        assert(c.size() == 6);
63        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
64        Eq eq = c.equal_range(1);
65        assert(std::distance(eq.first, eq.second) == 2);
66        C::const_iterator i = eq.first;
67        assert(i->first == 1);
68        assert(i->second == "one");
69        ++i;
70        assert(i->first == 1);
71        assert(i->second == "four");
72        eq = c.equal_range(2);
73        assert(std::distance(eq.first, eq.second) == 2);
74        i = eq.first;
75        assert(i->first == 2);
76        assert(i->second == "two");
77        ++i;
78        assert(i->first == 2);
79        assert(i->second == "four");
80
81        eq = c.equal_range(3);
82        assert(std::distance(eq.first, eq.second) == 1);
83        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(std::distance(c.begin(), c.end()) == c.size());
92        assert(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<std::hash<int> >,
100                                   test_compare<std::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<std::hash<int> >(8),
116            test_compare<std::equal_to<int> >(9),
117            A(10)
118           );
119        C c(a, a + 2,
120            7,
121            test_hash<std::hash<int> >(2),
122            test_compare<std::equal_to<int> >(3),
123            A(10)
124           );
125        c = std::move(c0);
126        assert(c.bucket_count() == 7);
127        assert(c.size() == 6);
128        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
129        Eq eq = c.equal_range(1);
130        assert(std::distance(eq.first, eq.second) == 2);
131        C::const_iterator i = eq.first;
132        assert(i->first == 1);
133        assert(i->second == "one");
134        ++i;
135        assert(i->first == 1);
136        assert(i->second == "four");
137        eq = c.equal_range(2);
138        assert(std::distance(eq.first, eq.second) == 2);
139        i = eq.first;
140        assert(i->first == 2);
141        assert(i->second == "two");
142        ++i;
143        assert(i->first == 2);
144        assert(i->second == "four");
145
146        eq = c.equal_range(3);
147        assert(std::distance(eq.first, eq.second) == 1);
148        i = eq.first;
149        assert(i->first == 3);
150        assert(i->second == "three");
151        eq = c.equal_range(4);
152        assert(std::distance(eq.first, eq.second) == 1);
153        i = eq.first;
154        assert(i->first == 4);
155        assert(i->second == "four");
156        assert(std::distance(c.begin(), c.end()) == c.size());
157        assert(std::distance(c.cbegin(), c.cend()) == c.size());
158        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
159        assert(c.max_load_factor() == 1);
160    }
161    {
162        typedef other_allocator<std::pair<const int, std::string> > A;
163        typedef std::unordered_multimap<int, std::string,
164                                   test_hash<std::hash<int> >,
165                                   test_compare<std::equal_to<int> >,
166                                   A
167                                   > C;
168        typedef std::pair<int, std::string> P;
169        P a[] =
170        {
171            P(1, "one"),
172            P(2, "two"),
173            P(3, "three"),
174            P(4, "four"),
175            P(1, "four"),
176            P(2, "four"),
177        };
178        C c0(a, a + sizeof(a)/sizeof(a[0]),
179            7,
180            test_hash<std::hash<int> >(8),
181            test_compare<std::equal_to<int> >(9),
182            A(10)
183           );
184        C c(a, a + 2,
185            7,
186            test_hash<std::hash<int> >(2),
187            test_compare<std::equal_to<int> >(3),
188            A(4)
189           );
190        c = std::move(c0);
191        assert(c.bucket_count() == 7);
192        assert(c.size() == 6);
193        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
194        Eq eq = c.equal_range(1);
195        assert(std::distance(eq.first, eq.second) == 2);
196        C::const_iterator i = eq.first;
197        assert(i->first == 1);
198        assert(i->second == "one");
199        ++i;
200        assert(i->first == 1);
201        assert(i->second == "four");
202        eq = c.equal_range(2);
203        assert(std::distance(eq.first, eq.second) == 2);
204        i = eq.first;
205        assert(i->first == 2);
206        assert(i->second == "two");
207        ++i;
208        assert(i->first == 2);
209        assert(i->second == "four");
210
211        eq = c.equal_range(3);
212        assert(std::distance(eq.first, eq.second) == 1);
213        i = eq.first;
214        assert(i->first == 3);
215        assert(i->second == "three");
216        eq = c.equal_range(4);
217        assert(std::distance(eq.first, eq.second) == 1);
218        i = eq.first;
219        assert(i->first == 4);
220        assert(i->second == "four");
221        assert(std::distance(c.begin(), c.end()) == c.size());
222        assert(std::distance(c.cbegin(), c.cend()) == c.size());
223        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
224        assert(c.max_load_factor() == 1);
225    }
226#if __cplusplus >= 201103L
227    {
228        typedef min_allocator<std::pair<const int, std::string> > A;
229        typedef std::unordered_multimap<int, std::string,
230                                   test_hash<std::hash<int> >,
231                                   test_compare<std::equal_to<int> >,
232                                   A
233                                   > C;
234        typedef std::pair<int, std::string> P;
235        P a[] =
236        {
237            P(1, "one"),
238            P(2, "two"),
239            P(3, "three"),
240            P(4, "four"),
241            P(1, "four"),
242            P(2, "four"),
243        };
244        C c0(a, a + sizeof(a)/sizeof(a[0]),
245            7,
246            test_hash<std::hash<int> >(8),
247            test_compare<std::equal_to<int> >(9),
248            A()
249           );
250        C c(a, a + 2,
251            7,
252            test_hash<std::hash<int> >(2),
253            test_compare<std::equal_to<int> >(3),
254            A()
255           );
256        c = std::move(c0);
257        assert(c.bucket_count() == 7);
258        assert(c.size() == 6);
259        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
260        Eq eq = c.equal_range(1);
261        assert(std::distance(eq.first, eq.second) == 2);
262        C::const_iterator i = eq.first;
263        assert(i->first == 1);
264        assert(i->second == "one");
265        ++i;
266        assert(i->first == 1);
267        assert(i->second == "four");
268        eq = c.equal_range(2);
269        assert(std::distance(eq.first, eq.second) == 2);
270        i = eq.first;
271        assert(i->first == 2);
272        assert(i->second == "two");
273        ++i;
274        assert(i->first == 2);
275        assert(i->second == "four");
276
277        eq = c.equal_range(3);
278        assert(std::distance(eq.first, eq.second) == 1);
279        i = eq.first;
280        assert(i->first == 3);
281        assert(i->second == "three");
282        eq = c.equal_range(4);
283        assert(std::distance(eq.first, eq.second) == 1);
284        i = eq.first;
285        assert(i->first == 4);
286        assert(i->second == "four");
287        assert(std::distance(c.begin(), c.end()) == c.size());
288        assert(std::distance(c.cbegin(), c.cend()) == c.size());
289        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
290        assert(c.max_load_factor() == 1);
291    }
292#endif
293#if _LIBCPP_DEBUG >= 1
294    {
295        std::unordered_multimap<int, int> s1 = {{1, 1}, {2, 2}, {3, 3}};
296        std::unordered_multimap<int, int>::iterator i = s1.begin();
297        std::pair<const int, int> k = *i;
298        std::unordered_multimap<int, int> s2;
299        s2 = std::move(s1);
300        assert(*i == k);
301        s2.erase(i);
302        assert(s2.size() == 2);
303    }
304#endif
305#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
306}
307