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