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#ifndef MAP_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H
10#define MAP_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H
11
12// <map>
13// <unordered_map>
14
15// class map
16// class unordered_map
17
18// insert(...);
19// emplace(...);
20// emplace_hint(...);
21
22// UNSUPPORTED: c++03
23
24#include <cassert>
25#include <iterator>
26
27#include "test_macros.h"
28#include "count_new.h"
29#include "container_test_types.h"
30
31
32template <class Container>
33void testMapInsert()
34{
35 typedef typename Container::value_type ValueTp;
36 ConstructController* cc = getConstructController();
37 cc->reset();
38 {
39 // Testing C::insert(const value_type&)
40 Container c;
41 const ValueTp v(42, 1);
42 cc->expect<const ValueTp&>();
43 assert(c.insert(v).second);
44 assert(!cc->unchecked());
45 {
46 DisableAllocationGuard g;
47 const ValueTp v2(42, 1);
48 assert(c.insert(v2).second == false);
49 }
50 }
51 {
52 // Testing C::insert(value_type&)
53 Container c;
54 ValueTp v(42, 1);
55 cc->expect<const ValueTp&>();
56 assert(c.insert(v).second);
57 assert(!cc->unchecked());
58 {
59 DisableAllocationGuard g;
60 ValueTp v2(42, 1);
61 assert(c.insert(v2).second == false);
62 }
63 }
64 {
65 // Testing C::insert(value_type&&)
66 Container c;
67 ValueTp v(42, 1);
68 cc->expect<ValueTp&&>();
69 assert(c.insert(std::move(v)).second);
70 assert(!cc->unchecked());
71 {
72 DisableAllocationGuard g;
73 ValueTp v2(42, 1);
74 assert(c.insert(std::move(v2)).second == false);
75 }
76 }
77 {
78 // Testing C::insert(const value_type&&)
79 Container c;
80 const ValueTp v(42, 1);
81 cc->expect<const ValueTp&>();
82 assert(c.insert(std::move(v)).second);
83 assert(!cc->unchecked());
84 {
85 DisableAllocationGuard g;
86 const ValueTp v2(42, 1);
87 assert(c.insert(std::move(v2)).second == false);
88 }
89 }
90 {
91 // Testing C::insert({key, value})
92 Container c;
93 cc->expect<ValueTp&&>();
94 assert(c.insert({42, 1}).second);
95 assert(!cc->unchecked());
96 {
97 DisableAllocationGuard g;
98 const ValueTp v2(42, 1);
99 assert(c.insert(std::move(v2)).second == false);
100 }
101 }
102 {
103 // Testing C::insert(std::initializer_list<ValueTp>)
104 Container c;
105 std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) };
106 cc->expect<ValueTp const&>(2);
107 c.insert(il);
108 assert(!cc->unchecked());
109 {
110 DisableAllocationGuard g;
111 c.insert(il);
112 }
113 }
114 {
115 // Testing C::insert(Iter, Iter) for *Iter = value_type const&
116 Container c;
117 const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) };
118 cc->expect<ValueTp const&>(3);
119 c.insert(std::begin(ValueList), std::end(ValueList));
120 assert(!cc->unchecked());
121 {
122 DisableAllocationGuard g;
123 c.insert(std::begin(ValueList), std::end(ValueList));
124 }
125 }
126 {
127 // Testing C::insert(Iter, Iter) for *Iter = value_type&&
128 Container c;
129 ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
130 cc->expect<ValueTp&&>(3);
131 c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
132 std::move_iterator<ValueTp*>(std::end(ValueList)));
133 assert(!cc->unchecked());
134 {
135 DisableAllocationGuard g;
136 ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
137 c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)),
138 std::move_iterator<ValueTp*>(std::end(ValueList2)));
139 }
140 }
141 {
142 // Testing C::insert(Iter, Iter) for *Iter = value_type&
143 Container c;
144 ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
145 cc->expect<ValueTp const&>(3);
146 c.insert(std::begin(ValueList), std::end(ValueList));
147 assert(!cc->unchecked());
148 {
149 DisableAllocationGuard g;
150 c.insert(std::begin(ValueList), std::end(ValueList));
151 }
152 }
153}
154
155
156template <class Container>
157void testMapInsertHint()
158{
159 typedef typename Container::value_type ValueTp;
160 typedef typename Container::key_type Key;
161 typedef typename Container::mapped_type Mapped;
162 typedef typename std::pair<Key, Mapped> NonConstKeyPair;
163 typedef Container C;
164 typedef typename C::iterator It;
165 ConstructController* cc = getConstructController();
166 cc->reset();
167 {
168 // Testing C::insert(p, const value_type&)
169 Container c;
170 const ValueTp v(42, 1);
171 cc->expect<const ValueTp&>();
172 It ret = c.insert(c.end(), v);
173 assert(ret != c.end());
174 assert(c.size() == 1);
175 assert(!cc->unchecked());
176 {
177 DisableAllocationGuard g;
178 const ValueTp v2(42, 1);
179 It ret2 = c.insert(c.begin(), v2);
180 assert(&(*ret2) == &(*ret));
181 assert(c.size() == 1);
182 }
183 }
184 {
185 // Testing C::insert(p, value_type&)
186 Container c;
187 ValueTp v(42, 1);
188 cc->expect<ValueTp const&>();
189 It ret = c.insert(c.end(), v);
190 assert(ret != c.end());
191 assert(c.size() == 1);
192 assert(!cc->unchecked());
193 {
194 DisableAllocationGuard g;
195 ValueTp v2(42, 1);
196 It ret2 = c.insert(c.begin(), v2);
197 assert(&(*ret2) == &(*ret));
198 assert(c.size() == 1);
199 }
200 }
201 {
202 // Testing C::insert(p, value_type&&)
203 Container c;
204 ValueTp v(42, 1);
205 cc->expect<ValueTp&&>();
206 It ret = c.insert(c.end(), std::move(v));
207 assert(ret != c.end());
208 assert(c.size() == 1);
209 assert(!cc->unchecked());
210 {
211 DisableAllocationGuard g;
212 ValueTp v2(42, 1);
213 It ret2 = c.insert(c.begin(), std::move(v2));
214 assert(&(*ret2) == &(*ret));
215 assert(c.size() == 1);
216 }
217 }
218 {
219 // Testing C::insert(p, {key, value})
220 Container c;
221 cc->expect<ValueTp&&>();
222 It ret = c.insert(c.end(), {42, 1});
223 assert(ret != c.end());
224 assert(c.size() == 1);
225 assert(!cc->unchecked());
226 {
227 DisableAllocationGuard g;
228 It ret2 = c.insert(c.begin(), {42, 1});
229 assert(&(*ret2) == &(*ret));
230 assert(c.size() == 1);
231 }
232 }
233 {
234 // Testing C::insert(p, const value_type&&)
235 Container c;
236 const ValueTp v(42, 1);
237 cc->expect<const ValueTp&>();
238 It ret = c.insert(c.end(), std::move(v));
239 assert(ret != c.end());
240 assert(c.size() == 1);
241 assert(!cc->unchecked());
242 {
243 DisableAllocationGuard g;
244 const ValueTp v2(42, 1);
245 It ret2 = c.insert(c.begin(), std::move(v2));
246 assert(&(*ret2) == &(*ret));
247 assert(c.size() == 1);
248 }
249 }
250 {
251 // Testing C::insert(p, pair<Key, Mapped> const&)
252 Container c;
253 const NonConstKeyPair v(42, 1);
254 cc->expect<const NonConstKeyPair&>();
255 It ret = c.insert(c.end(), v);
256 assert(ret != c.end());
257 assert(c.size() == 1);
258 assert(!cc->unchecked());
259 {
260 DisableAllocationGuard g;
261 const NonConstKeyPair v2(42, 1);
262 It ret2 = c.insert(c.begin(), v2);
263 assert(&(*ret2) == &(*ret));
264 assert(c.size() == 1);
265 }
266 }
267 {
268 // Testing C::insert(p, pair<Key, Mapped>&&)
269 Container c;
270 NonConstKeyPair v(42, 1);
271 cc->expect<NonConstKeyPair&&>();
272 It ret = c.insert(c.end(), std::move(v));
273 assert(ret != c.end());
274 assert(c.size() == 1);
275 assert(!cc->unchecked());
276 {
277 DisableAllocationGuard g;
278 NonConstKeyPair v2(42, 1);
279 It ret2 = c.insert(c.begin(), std::move(v2));
280 assert(&(*ret2) == &(*ret));
281 assert(c.size() == 1);
282 }
283 }
284
285
286}
287
288
289template <class Container>
290void testMapEmplace()
291{
292 typedef typename Container::value_type ValueTp;
293 typedef typename Container::key_type Key;
294 typedef typename Container::mapped_type Mapped;
295 typedef typename std::pair<Key, Mapped> NonConstKeyPair;
296 ConstructController* cc = getConstructController();
297 cc->reset();
298 {
299 // Testing C::emplace(const value_type&)
300 Container c;
301 const ValueTp v(42, 1);
302 cc->expect<const ValueTp&>();
303 assert(c.emplace(v).second);
304 assert(!cc->unchecked());
305 {
306 DisableAllocationGuard g;
307 const ValueTp v2(42, 1);
308 assert(c.emplace(v2).second == false);
309 }
310 }
311 {
312 // Testing C::emplace(value_type&)
313 Container c;
314 ValueTp v(42, 1);
315 cc->expect<ValueTp&>();
316 assert(c.emplace(v).second);
317 assert(!cc->unchecked());
318 {
319 DisableAllocationGuard g;
320 ValueTp v2(42, 1);
321 assert(c.emplace(v2).second == false);
322 }
323 }
324 {
325 // Testing C::emplace(value_type&&)
326 Container c;
327 ValueTp v(42, 1);
328 cc->expect<ValueTp&&>();
329 assert(c.emplace(std::move(v)).second);
330 assert(!cc->unchecked());
331 {
332 DisableAllocationGuard g;
333 ValueTp v2(42, 1);
334 assert(c.emplace(std::move(v2)).second == false);
335 }
336 }
337 {
338 // Testing C::emplace(const value_type&&)
339 Container c;
340 const ValueTp v(42, 1);
341 cc->expect<const ValueTp&&>();
342 assert(c.emplace(std::move(v)).second);
343 assert(!cc->unchecked());
344 {
345 DisableAllocationGuard g;
346 const ValueTp v2(42, 1);
347 assert(c.emplace(std::move(v2)).second == false);
348 }
349 }
350 {
351 // Testing C::emplace(pair<Key, Mapped> const&)
352 Container c;
353 const NonConstKeyPair v(42, 1);
354 cc->expect<const NonConstKeyPair&>();
355 assert(c.emplace(v).second);
356 assert(!cc->unchecked());
357 {
358 DisableAllocationGuard g;
359 const NonConstKeyPair v2(42, 1);
360 assert(c.emplace(v2).second == false);
361 }
362 }
363 {
364 // Testing C::emplace(pair<Key, Mapped> &&)
365 Container c;
366 NonConstKeyPair v(42, 1);
367 cc->expect<NonConstKeyPair&&>();
368 assert(c.emplace(std::move(v)).second);
369 assert(!cc->unchecked());
370 {
371 DisableAllocationGuard g;
372 NonConstKeyPair v2(42, 1);
373 assert(c.emplace(std::move(v2)).second == false);
374 }
375 }
376 {
377 // Testing C::emplace(const Key&, ConvertibleToMapped&&)
378 Container c;
379 const Key k(42);
380 cc->expect<Key const&, int&&>();
381 assert(c.emplace(k, 1).second);
382 assert(!cc->unchecked());
383 {
384 DisableAllocationGuard g;
385 const Key k2(42);
386 assert(c.emplace(k2, 2).second == false);
387 }
388 }
389 {
390 // Testing C::emplace(Key&, Mapped&)
391 Container c;
392 Key k(42);
393 Mapped m(1);
394 cc->expect<Key&, Mapped&>();
395 assert(c.emplace(k, m).second);
396 assert(!cc->unchecked());
397 {
398 DisableAllocationGuard g;
399 Key k2(42);
400 assert(c.emplace(k2, m).second == false);
401 }
402 }
403 {
404 // Testing C::emplace(Key&&, Mapped&&)
405 Container c;
406 Key k(42);
407 Mapped m(1);
408 cc->expect<Key&&, Mapped&&>();
409 assert(c.emplace(std::move(k), std::move(m)).second);
410 assert(!cc->unchecked());
411 {
412 DisableAllocationGuard g;
413 Key k2(42);
414 Mapped m2(2);
415 assert(c.emplace(std::move(k2), std::move(m2)).second == false);
416 }
417 }
418 {
419 // Testing C::emplace(ConvertibleToKey&&, ConvertibleToMapped&&)
420 Container c;
421 cc->expect<int&&, int&&>();
422 assert(c.emplace(42, 1).second);
423 assert(!cc->unchecked());
424 {
425 // test that emplacing a duplicate item allocates. We cannot optimize
426 // this case because int&& does not match the type of key exactly.
427 cc->expect<int&&, int&&>();
428 assert(c.emplace(42, 1).second == false);
429 assert(!cc->unchecked());
430 }
431 }
432}
433
434
435template <class Container>
436void testMapEmplaceHint()
437{
438 typedef typename Container::value_type ValueTp;
439 typedef typename Container::key_type Key;
440 typedef typename Container::mapped_type Mapped;
441 typedef typename std::pair<Key, Mapped> NonConstKeyPair;
442 typedef Container C;
443 typedef typename C::iterator It;
444 ConstructController* cc = getConstructController();
445 cc->reset();
446 {
447 // Testing C::emplace_hint(p, const value_type&)
448 Container c;
449 const ValueTp v(42, 1);
450 cc->expect<const ValueTp&>();
451 It ret = c.emplace_hint(c.end(), v);
452 assert(ret != c.end());
453 assert(c.size() == 1);
454 assert(!cc->unchecked());
455 {
456 DisableAllocationGuard g;
457 const ValueTp v2(42, 1);
458 It ret2 = c.emplace_hint(c.begin(), v2);
459 assert(&(*ret2) == &(*ret));
460 assert(c.size() == 1);
461 }
462 }
463 {
464 // Testing C::emplace_hint(p, value_type&)
465 Container c;
466 ValueTp v(42, 1);
467 cc->expect<ValueTp&>();
468 It ret = c.emplace_hint(c.end(), v);
469 assert(ret != c.end());
470 assert(c.size() == 1);
471 assert(!cc->unchecked());
472 {
473 DisableAllocationGuard g;
474 ValueTp v2(42, 1);
475 It ret2 = c.emplace_hint(c.begin(), v2);
476 assert(&(*ret2) == &(*ret));
477 assert(c.size() == 1);
478 }
479 }
480 {
481 // Testing C::emplace_hint(p, value_type&&)
482 Container c;
483 ValueTp v(42, 1);
484 cc->expect<ValueTp&&>();
485 It ret = c.emplace_hint(c.end(), std::move(v));
486 assert(ret != c.end());
487 assert(c.size() == 1);
488 assert(!cc->unchecked());
489 {
490 DisableAllocationGuard g;
491 ValueTp v2(42, 1);
492 It ret2 = c.emplace_hint(c.begin(), std::move(v2));
493 assert(&(*ret2) == &(*ret));
494 assert(c.size() == 1);
495 }
496 }
497 {
498 // Testing C::emplace_hint(p, const value_type&&)
499 Container c;
500 const ValueTp v(42, 1);
501 cc->expect<const ValueTp&&>();
502 It ret = c.emplace_hint(c.end(), std::move(v));
503 assert(ret != c.end());
504 assert(c.size() == 1);
505 assert(!cc->unchecked());
506 {
507 DisableAllocationGuard g;
508 const ValueTp v2(42, 1);
509 It ret2 = c.emplace_hint(c.begin(), std::move(v2));
510 assert(&(*ret2) == &(*ret));
511 assert(c.size() == 1);
512 }
513 }
514 {
515 // Testing C::emplace_hint(p, pair<Key, Mapped> const&)
516 Container c;
517 const NonConstKeyPair v(42, 1);
518 cc->expect<const NonConstKeyPair&>();
519 It ret = c.emplace_hint(c.end(), v);
520 assert(ret != c.end());
521 assert(c.size() == 1);
522 assert(!cc->unchecked());
523 {
524 DisableAllocationGuard g;
525 const NonConstKeyPair v2(42, 1);
526 It ret2 = c.emplace_hint(c.begin(), v2);
527 assert(&(*ret2) == &(*ret));
528 assert(c.size() == 1);
529 }
530 }
531 {
532 // Testing C::emplace_hint(p, pair<Key, Mapped>&&)
533 Container c;
534 NonConstKeyPair v(42, 1);
535 cc->expect<NonConstKeyPair&&>();
536 It ret = c.emplace_hint(c.end(), std::move(v));
537 assert(ret != c.end());
538 assert(c.size() == 1);
539 assert(!cc->unchecked());
540 {
541 DisableAllocationGuard g;
542 NonConstKeyPair v2(42, 1);
543 It ret2 = c.emplace_hint(c.begin(), std::move(v2));
544 assert(&(*ret2) == &(*ret));
545 assert(c.size() == 1);
546 }
547 }
548 {
549 // Testing C::emplace_hint(p, const Key&, ConvertibleToMapped&&)
550 Container c;
551 const Key k(42);
552 cc->expect<Key const&, int&&>();
553 It ret = c.emplace_hint(c.end(), k, 42);
554 assert(ret != c.end());
555 assert(c.size() == 1);
556 assert(!cc->unchecked());
557 {
558 DisableAllocationGuard g;
559 const Key k2(42);
560 It ret2 = c.emplace_hint(c.begin(), k2, 1);
561 assert(&(*ret2) == &(*ret));
562 assert(c.size() == 1);
563 }
564 }
565 {
566 // Testing C::emplace_hint(p, Key&, Mapped&)
567 Container c;
568 Key k(42);
569 Mapped m(1);
570 cc->expect<Key&, Mapped&>();
571 It ret = c.emplace_hint(c.end(), k, m);
572 assert(ret != c.end());
573 assert(c.size() == 1);
574 assert(!cc->unchecked());
575 {
576 DisableAllocationGuard g;
577 Key k2(42);
578 Mapped m2(2);
579 It ret2 = c.emplace_hint(c.begin(), k2, m2);
580 assert(&(*ret2) == &(*ret));
581 assert(c.size() == 1);
582 }
583 }
584 {
585 // Testing C::emplace_hint(p, Key&&, Mapped&&)
586 Container c;
587 Key k(42);
588 Mapped m(1);
589 cc->expect<Key&&, Mapped&&>();
590 It ret = c.emplace_hint(c.end(), std::move(k), std::move(m));
591 assert(ret != c.end());
592 assert(c.size() == 1);
593 assert(!cc->unchecked());
594 {
595 DisableAllocationGuard g;
596 Key k2(42);
597 Mapped m2(2);
598 It ret2 = c.emplace_hint(c.begin(), std::move(k2), std::move(m2));
599 assert(&(*ret2) == &(*ret));
600 assert(c.size() == 1);
601 }
602 }
603 {
604 // Testing C::emplace_hint(p, ConvertibleToKey&&, ConvertibleToMapped&&)
605 Container c;
606 cc->expect<int&&, int&&>();
607 It ret = c.emplace_hint(c.end(), 42, 1);
608 assert(ret != c.end());
609 assert(c.size() == 1);
610 assert(!cc->unchecked());
611 {
612 cc->expect<int&&, int&&>();
613 It ret2 = c.emplace_hint(c.begin(), 42, 2);
614 assert(&(*ret2) == &(*ret));
615 assert(c.size() == 1);
616 assert(!cc->unchecked());
617 }
618 }
619
620}
621
622
623template <class Container>
624void testMultimapInsert()
625{
626 typedef typename Container::value_type ValueTp;
627 ConstructController* cc = getConstructController();
628 cc->reset();
629 {
630 // Testing C::insert(const value_type&)
631 Container c;
632 const ValueTp v(42, 1);
633 cc->expect<const ValueTp&>();
634 c.insert(v);
635 assert(!cc->unchecked());
636 }
637 {
638 // Testing C::insert(value_type&)
639 Container c;
640 ValueTp v(42, 1);
641 cc->expect<ValueTp&>();
642 c.insert(v);
643 assert(!cc->unchecked());
644 }
645 {
646 // Testing C::insert(value_type&&)
647 Container c;
648 ValueTp v(42, 1);
649 cc->expect<ValueTp&&>();
650 c.insert(std::move(v));
651 assert(!cc->unchecked());
652 }
653 {
654 // Testing C::insert({key, value})
655 Container c;
656 cc->expect<ValueTp&&>();
657 c.insert({42, 1});
658 assert(!cc->unchecked());
659 }
660 {
661 // Testing C::insert(std::initializer_list<ValueTp>)
662 Container c;
663 std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) };
664 cc->expect<ValueTp const&>(2);
665 c.insert(il);
666 assert(!cc->unchecked());
667 }
668 {
669 // Testing C::insert(Iter, Iter) for *Iter = value_type const&
670 Container c;
671 const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) };
672 cc->expect<ValueTp const&>(3);
673 c.insert(std::begin(ValueList), std::end(ValueList));
674 assert(!cc->unchecked());
675 }
676 {
677 // Testing C::insert(Iter, Iter) for *Iter = value_type&&
678 Container c;
679 ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
680 cc->expect<ValueTp&&>(3);
681 c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
682 std::move_iterator<ValueTp*>(std::end(ValueList)));
683 assert(!cc->unchecked());
684 }
685 {
686 // Testing C::insert(Iter, Iter) for *Iter = value_type&
687 Container c;
688 ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
689 cc->expect<ValueTp&>(3);
690 c.insert(std::begin(ValueList), std::end(ValueList));
691 assert(!cc->unchecked());
692 }
693}
694
695
696template <class Container>
697void testMultimapInsertHint()
698{
699 typedef typename Container::value_type ValueTp;
700 ConstructController* cc = getConstructController();
701 cc->reset();
702 {
703 // Testing C::insert(p, const value_type&)
704 Container c;
705 const ValueTp v(42, 1);
706 cc->expect<const ValueTp&>();
707 c.insert(c.begin(), v);
708 assert(!cc->unchecked());
709 }
710 {
711 // Testing C::insert(p, value_type&)
712 Container c;
713 ValueTp v(42, 1);
714 cc->expect<ValueTp&>();
715 c.insert(c.begin(), v);
716 assert(!cc->unchecked());
717 }
718 {
719 // Testing C::insert(p, value_type&&)
720 Container c;
721 ValueTp v(42, 1);
722 cc->expect<ValueTp&&>();
723 c.insert(c.begin(), std::move(v));
724 assert(!cc->unchecked());
725 }
726 {
727 // Testing C::insert(p, {key, value})
728 Container c;
729 cc->expect<ValueTp&&>();
730 c.insert(c.begin(), {42, 1});
731 assert(!cc->unchecked());
732 }
733}
734
735#endif
736

source code of libcxx/test/std/containers/map_allocator_requirement_test_templates.h