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// size_type erase(const key_type& k);
16
17#include <unordered_map>
18#include <string>
19#include <set>
20#include <cassert>
21#include <cstddef>
22
23#include "test_macros.h"
24#include "../../../check_consecutive.h"
25#include "min_allocator.h"
26
27#if TEST_STD_VER >= 11
28template <typename Unordered>
29bool only_deletions(const Unordered& whole, const Unordered& part) {
30 typename Unordered::const_iterator w = whole.begin();
31 typename Unordered::const_iterator p = part.begin();
32
33 while (w != whole.end() && p != part.end()) {
34 if (*w == *p)
35 p++;
36 w++;
37 }
38
39 return p == part.end();
40}
41#endif
42
43int main(int, char**) {
44 {
45 typedef std::unordered_multimap<int, std::string> C;
46 typedef std::pair<int, std::string> P;
47 P a[] = {
48 P(1, "one"),
49 P(2, "two"),
50 P(3, "three"),
51 P(4, "four"),
52 P(1, "four"),
53 P(2, "four"),
54 };
55 C c(a, a + sizeof(a) / sizeof(a[0]));
56 assert(c.erase(5) == 0);
57 assert(c.size() == 6);
58 typedef std::pair<C::const_iterator, C::const_iterator> Eq;
59 Eq eq = c.equal_range(x: 1);
60 assert(std::distance(eq.first, eq.second) == 2);
61 std::multiset<std::string> s;
62 s.insert(x: "one");
63 s.insert(x: "four");
64 CheckConsecutiveKeys<C::const_iterator>(pos: c.find(x: 1), end: c.end(), key: 1, values&: s);
65 eq = c.equal_range(x: 2);
66 assert(std::distance(eq.first, eq.second) == 2);
67 s.insert(x: "two");
68 s.insert(x: "four");
69 CheckConsecutiveKeys<C::const_iterator>(pos: c.find(x: 2), end: c.end(), key: 2, values&: s);
70 eq = c.equal_range(x: 3);
71 assert(std::distance(eq.first, eq.second) == 1);
72 C::const_iterator k = eq.first;
73 assert(k->first == 3);
74 assert(k->second == "three");
75 eq = c.equal_range(x: 4);
76 assert(std::distance(eq.first, eq.second) == 1);
77 k = eq.first;
78 assert(k->first == 4);
79 assert(k->second == "four");
80 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
81 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
82
83 assert(c.erase(2) == 2);
84 assert(c.size() == 4);
85 eq = c.equal_range(x: 1);
86 assert(std::distance(eq.first, eq.second) == 2);
87 s.insert(x: "one");
88 s.insert(x: "four");
89 CheckConsecutiveKeys<C::const_iterator>(pos: c.find(x: 1), end: c.end(), key: 1, values&: s);
90 eq = c.equal_range(x: 3);
91 assert(std::distance(eq.first, eq.second) == 1);
92 k = eq.first;
93 assert(k->first == 3);
94 assert(k->second == "three");
95 eq = c.equal_range(x: 4);
96 assert(std::distance(eq.first, eq.second) == 1);
97 k = eq.first;
98 assert(k->first == 4);
99 assert(k->second == "four");
100 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
101 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
102
103 assert(c.erase(2) == 0);
104 assert(c.size() == 4);
105 eq = c.equal_range(x: 1);
106 assert(std::distance(eq.first, eq.second) == 2);
107 s.insert(x: "one");
108 s.insert(x: "four");
109 CheckConsecutiveKeys<C::const_iterator>(pos: c.find(x: 1), end: c.end(), key: 1, values&: s);
110 eq = c.equal_range(x: 3);
111 assert(std::distance(eq.first, eq.second) == 1);
112 k = eq.first;
113 assert(k->first == 3);
114 assert(k->second == "three");
115 eq = c.equal_range(x: 4);
116 assert(std::distance(eq.first, eq.second) == 1);
117 k = eq.first;
118 assert(k->first == 4);
119 assert(k->second == "four");
120 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
121 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
122
123 assert(c.erase(4) == 1);
124 assert(c.size() == 3);
125 eq = c.equal_range(x: 1);
126 assert(std::distance(eq.first, eq.second) == 2);
127 s.insert(x: "one");
128 s.insert(x: "four");
129 CheckConsecutiveKeys<C::const_iterator>(pos: c.find(x: 1), end: c.end(), key: 1, values&: s);
130 eq = c.equal_range(x: 3);
131 assert(std::distance(eq.first, eq.second) == 1);
132 k = eq.first;
133 assert(k->first == 3);
134 assert(k->second == "three");
135 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
136 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
137
138 assert(c.erase(4) == 0);
139 assert(c.size() == 3);
140 eq = c.equal_range(x: 1);
141 assert(std::distance(eq.first, eq.second) == 2);
142 s.insert(x: "one");
143 s.insert(x: "four");
144 CheckConsecutiveKeys<C::const_iterator>(pos: c.find(x: 1), end: c.end(), key: 1, values&: s);
145 eq = c.equal_range(x: 3);
146 assert(std::distance(eq.first, eq.second) == 1);
147 k = eq.first;
148 assert(k->first == 3);
149 assert(k->second == "three");
150 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
151 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
152
153 assert(c.erase(1) == 2);
154 assert(c.size() == 1);
155 eq = c.equal_range(x: 3);
156 assert(std::distance(eq.first, eq.second) == 1);
157 k = eq.first;
158 assert(k->first == 3);
159 assert(k->second == "three");
160 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
161 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
162
163 assert(c.erase(1) == 0);
164 assert(c.size() == 1);
165 eq = c.equal_range(x: 3);
166 assert(std::distance(eq.first, eq.second) == 1);
167 k = eq.first;
168 assert(k->first == 3);
169 assert(k->second == "three");
170 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
171 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
172
173 assert(c.erase(3) == 1);
174 assert(c.size() == 0);
175 eq = c.equal_range(x: 3);
176 assert(std::distance(eq.first, eq.second) == 0);
177 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
178 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
179
180 assert(c.erase(3) == 0);
181 assert(c.size() == 0);
182 eq = c.equal_range(x: 3);
183 assert(std::distance(eq.first, eq.second) == 0);
184 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
185 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
186 }
187#if TEST_STD_VER >= 11
188 {
189 typedef std::unordered_multimap<int,
190 std::string,
191 std::hash<int>,
192 std::equal_to<int>,
193 min_allocator<std::pair<const int, std::string>>>
194 C;
195 typedef std::pair<int, std::string> P;
196 P a[] = {
197 P(1, "one"),
198 P(2, "two"),
199 P(3, "three"),
200 P(4, "four"),
201 P(1, "four"),
202 P(2, "four"),
203 };
204 C c(a, a + sizeof(a) / sizeof(a[0]));
205 assert(c.erase(5) == 0);
206 assert(c.size() == 6);
207 typedef std::pair<C::const_iterator, C::const_iterator> Eq;
208 Eq eq = c.equal_range(1);
209 assert(std::distance(eq.first, eq.second) == 2);
210 std::multiset<std::string> s;
211 s.insert("one");
212 s.insert("four");
213 CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
214 eq = c.equal_range(2);
215 assert(std::distance(eq.first, eq.second) == 2);
216 s.insert("two");
217 s.insert("four");
218 CheckConsecutiveKeys<C::const_iterator>(c.find(2), c.end(), 2, s);
219 eq = c.equal_range(3);
220 assert(std::distance(eq.first, eq.second) == 1);
221 C::const_iterator k = eq.first;
222 assert(k->first == 3);
223 assert(k->second == "three");
224 eq = c.equal_range(4);
225 assert(std::distance(eq.first, eq.second) == 1);
226 k = eq.first;
227 assert(k->first == 4);
228 assert(k->second == "four");
229 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
230 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
231
232 assert(c.erase(2) == 2);
233 assert(c.size() == 4);
234 eq = c.equal_range(1);
235 assert(std::distance(eq.first, eq.second) == 2);
236 s.insert("one");
237 s.insert("four");
238 CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
239 eq = c.equal_range(3);
240 assert(std::distance(eq.first, eq.second) == 1);
241 k = eq.first;
242 assert(k->first == 3);
243 assert(k->second == "three");
244 eq = c.equal_range(4);
245 assert(std::distance(eq.first, eq.second) == 1);
246 k = eq.first;
247 assert(k->first == 4);
248 assert(k->second == "four");
249 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
250 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
251
252 assert(c.erase(2) == 0);
253 assert(c.size() == 4);
254 eq = c.equal_range(1);
255 assert(std::distance(eq.first, eq.second) == 2);
256 s.insert("one");
257 s.insert("four");
258 CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
259 eq = c.equal_range(3);
260 assert(std::distance(eq.first, eq.second) == 1);
261 k = eq.first;
262 assert(k->first == 3);
263 assert(k->second == "three");
264 eq = c.equal_range(4);
265 assert(std::distance(eq.first, eq.second) == 1);
266 k = eq.first;
267 assert(k->first == 4);
268 assert(k->second == "four");
269 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
270 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
271
272 assert(c.erase(4) == 1);
273 assert(c.size() == 3);
274 eq = c.equal_range(1);
275 assert(std::distance(eq.first, eq.second) == 2);
276 s.insert("one");
277 s.insert("four");
278 CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
279 eq = c.equal_range(3);
280 assert(std::distance(eq.first, eq.second) == 1);
281 k = eq.first;
282 assert(k->first == 3);
283 assert(k->second == "three");
284 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
285 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
286
287 assert(c.erase(4) == 0);
288 assert(c.size() == 3);
289 eq = c.equal_range(1);
290 assert(std::distance(eq.first, eq.second) == 2);
291 s.insert("one");
292 s.insert("four");
293 CheckConsecutiveKeys<C::const_iterator>(c.find(1), c.end(), 1, s);
294 eq = c.equal_range(3);
295 assert(std::distance(eq.first, eq.second) == 1);
296 k = eq.first;
297 assert(k->first == 3);
298 assert(k->second == "three");
299 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
300 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
301
302 assert(c.erase(1) == 2);
303 assert(c.size() == 1);
304 eq = c.equal_range(3);
305 assert(std::distance(eq.first, eq.second) == 1);
306 k = eq.first;
307 assert(k->first == 3);
308 assert(k->second == "three");
309 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
310 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
311
312 assert(c.erase(1) == 0);
313 assert(c.size() == 1);
314 eq = c.equal_range(3);
315 assert(std::distance(eq.first, eq.second) == 1);
316 k = eq.first;
317 assert(k->first == 3);
318 assert(k->second == "three");
319 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
320 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
321
322 assert(c.erase(3) == 1);
323 assert(c.size() == 0);
324 eq = c.equal_range(3);
325 assert(std::distance(eq.first, eq.second) == 0);
326 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
327 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
328
329 assert(c.erase(3) == 0);
330 assert(c.size() == 0);
331 eq = c.equal_range(3);
332 assert(std::distance(eq.first, eq.second) == 0);
333 assert(static_cast<std::size_t>(std::distance(c.begin(), c.end())) == c.size());
334 assert(static_cast<std::size_t>(std::distance(c.cbegin(), c.cend())) == c.size());
335 }
336 {
337 typedef std::unordered_multimap<int, int> C;
338 C m, m2;
339 for (int i = 0; i < 10; ++i) {
340 for (int j = 0; j < 2; ++j) {
341 m.insert(std::make_pair(i, j));
342 m2.insert(std::make_pair(i, j));
343 }
344 }
345
346 C::iterator i = m2.begin();
347 int ctr = 0;
348 while (i != m2.end()) {
349 if (ctr++ % 2 == 0)
350 m2.erase(i++);
351 else
352 ++i;
353 }
354
355 assert(only_deletions(m, m2));
356 }
357#endif
358
359 return 0;
360}
361

source code of libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp