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 // <unordered_map>
10 
11 // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
12 //           class Alloc = allocator<pair<const Key, T>>>
13 // class unordered_multimap
14 
15 // unordered_multimap& operator=(const unordered_multimap& u);
16 
17 #include <unordered_map>
18 #include <string>
19 #include <set>
20 #include <cassert>
21 #include <cfloat>
22 #include <cmath>
23 #include <algorithm>
24 #include <cstddef>
25 
26 #include "test_macros.h"
27 #include "../../../check_consecutive.h"
28 #include "../../../test_compare.h"
29 #include "../../../test_hash.h"
30 #include "test_allocator.h"
31 #include "min_allocator.h"
32 
main(int,char **)33 int main(int, char**)
34 {
35     {
36         typedef test_allocator<std::pair<const int, std::string> > A;
37         typedef std::unordered_multimap<int, std::string,
38                                    test_hash<int>,
39                                    test_equal_to<int>,
40                                    A
41                                    > C;
42         typedef std::pair<int, std::string> P;
43         P a[] =
44         {
45             P(1, "one"),
46             P(2, "two"),
47             P(3, "three"),
48             P(4, "four"),
49             P(1, "four"),
50             P(2, "four"),
51         };
52         C c0(a, a + sizeof(a)/sizeof(a[0]),
53             7,
54             test_hash<int>(8),
55             test_equal_to<int>(9),
56             A(10)
57            );
58         C c(a, a + 2,
59             7,
60             test_hash<int>(2),
61             test_equal_to<int>(3),
62             A(4)
63            );
64         c = c0;
65         LIBCPP_ASSERT(c.bucket_count() == 7);
66         assert(c.size() == 6);
67         std::multiset<std::string> s;
68         s.insert("one");
69         s.insert("four");
70         CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
71         s.insert("two");
72         s.insert("four");
73         CheckConsecutiveKeys<C::const_iterator>(c.find(2), c.end(), 2, s);
74         s.insert("three");
75         CheckConsecutiveKeys<C::const_iterator>(c.find(3), c.end(), 3, s);
76         s.insert("four");
77         CheckConsecutiveKeys<C::const_iterator>(c.find(4), c.end(), 4, s);
78         assert(c.hash_function() == test_hash<int>(8));
79         assert(c.key_eq() == test_equal_to<int>(9));
80         assert(c.get_allocator() == A(4));
81         assert(!c.empty());
82         assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
83         assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
84         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
85         assert(c.max_load_factor() == 1);
86     }
87     {
88         typedef std::unordered_multimap<int, std::string> C;
89         typedef std::pair<const int, std::string> P;
90         const P a[] =
91         {
92             P(1, "one"),
93             P(2, "two"),
94             P(3, "three"),
95             P(4, "four"),
96             P(1, "four"),
97             P(2, "four"),
98         };
99         C c(a, a+sizeof(a)/sizeof(a[0]));
100         C *p = &c;
101         c = *p;
102         assert(c.size() == 6);
103         assert(std::is_permutation(c.begin(), c.end(), a));
104     }
105     {
106         typedef other_allocator<std::pair<const int, std::string> > A;
107         typedef std::unordered_multimap<int, std::string,
108                                    test_hash<int>,
109                                    test_equal_to<int>,
110                                    A
111                                    > C;
112         typedef std::pair<int, std::string> P;
113         P a[] =
114         {
115             P(1, "one"),
116             P(2, "two"),
117             P(3, "three"),
118             P(4, "four"),
119             P(1, "four"),
120             P(2, "four"),
121         };
122         C c0(a, a + sizeof(a)/sizeof(a[0]),
123             7,
124             test_hash<int>(8),
125             test_equal_to<int>(9),
126             A(10)
127            );
128         C c(a, a + 2,
129             7,
130             test_hash<int>(2),
131             test_equal_to<int>(3),
132             A(4)
133            );
134         c = c0;
135         assert(c.bucket_count() >= 7);
136         assert(c.size() == 6);
137         std::multiset<std::string> s;
138         s.insert("one");
139         s.insert("four");
140         CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
141         s.insert("two");
142         s.insert("four");
143         CheckConsecutiveKeys<C::const_iterator>(c.find(2), c.end(), 2, s);
144         s.insert("three");
145         CheckConsecutiveKeys<C::const_iterator>(c.find(3), c.end(), 3, s);
146         s.insert("four");
147         CheckConsecutiveKeys<C::const_iterator>(c.find(4), c.end(), 4, s);
148         assert(c.hash_function() == test_hash<int>(8));
149         assert(c.key_eq() == test_equal_to<int>(9));
150         assert(c.get_allocator() == A(10));
151         assert(!c.empty());
152         assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
153         assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
154         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
155         assert(c.max_load_factor() == 1);
156     }
157 #if TEST_STD_VER >= 11
158     {
159         typedef min_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()
180            );
181         C c(a, a + 2,
182             7,
183             test_hash<int>(2),
184             test_equal_to<int>(3),
185             A()
186            );
187         c = c0;
188         LIBCPP_ASSERT(c.bucket_count() == 7);
189         assert(c.size() == 6);
190         std::multiset<std::string> s;
191         s.insert("one");
192         s.insert("four");
193         CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
194         s.insert("two");
195         s.insert("four");
196         CheckConsecutiveKeys<C::const_iterator>(c.find(2), c.end(), 2, s);
197         s.insert("three");
198         CheckConsecutiveKeys<C::const_iterator>(c.find(3), c.end(), 3, s);
199         s.insert("four");
200         CheckConsecutiveKeys<C::const_iterator>(c.find(4), c.end(), 4, s);
201         assert(c.hash_function() == test_hash<int>(8));
202         assert(c.key_eq() == test_equal_to<int>(9));
203         assert(c.get_allocator() == A());
204         assert(!c.empty());
205         assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
206         assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
207         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
208         assert(c.max_load_factor() == 1);
209     }
210 #endif
211 
212   return 0;
213 }
214