1 2 // Copyright 2006-2010 Daniel James. 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(PIECEWISE_TEST_NAME) 7 8 // clang-format off 9 #include "../helpers/prefix.hpp" 10 #include <boost/unordered_set.hpp> 11 #include <boost/unordered_map.hpp> 12 #include "../helpers/postfix.hpp" 13 // clang-format on 14 15 #include "../helpers/test.hpp" 16 #include "../objects/test.hpp" 17 #include "../helpers/random_values.hpp" 18 #include "../helpers/tracker.hpp" 19 #include "../helpers/equivalent.hpp" 20 #include "../helpers/invariants.hpp" 21 #include "../helpers/input_iterator.hpp" 22 #include "../helpers/helpers.hpp" 23 24 namespace insert_tests { 25 26 test::seed_t initialize_seed(243432); 27 28 template <class X> unique_insert_tests1(X *,test::random_generator generator)29 void unique_insert_tests1(X*, test::random_generator generator) 30 { 31 test::check_instances check_; 32 33 typedef typename X::iterator iterator; 34 typedef test::ordered<X> ordered; 35 36 UNORDERED_SUB_TEST("insert(value) tests for containers with unique keys") 37 { 38 X x; 39 test::ordered<X> tracker = test::create_ordered(x); 40 41 test::random_values<X> v(1000, generator); 42 43 for (typename test::random_values<X>::iterator it = v.begin(); 44 it != v.end(); ++it) { 45 46 typename X::size_type old_bucket_count = x.bucket_count(); 47 float b = x.max_load_factor(); 48 49 std::pair<iterator, bool> r1 = x.insert(*it); 50 std::pair<typename ordered::iterator, bool> r2 = tracker.insert(*it); 51 52 BOOST_TEST(r1.second == r2.second); 53 BOOST_TEST(*r1.first == *r2.first); 54 55 tracker.compare_key(x, *it); 56 57 if (static_cast<double>(x.size()) <= 58 b * static_cast<double>(old_bucket_count)) 59 BOOST_TEST(x.bucket_count() == old_bucket_count); 60 } 61 62 test::check_equivalent_keys(x); 63 } 64 65 UNORDERED_SUB_TEST("insert(rvalue) tests for containers with unique keys") 66 { 67 X x; 68 test::ordered<X> tracker = test::create_ordered(x); 69 70 test::random_values<X> v(1000, generator); 71 72 for (typename test::random_values<X>::iterator it = v.begin(); 73 it != v.end(); ++it) { 74 75 typename X::size_type old_bucket_count = x.bucket_count(); 76 float b = x.max_load_factor(); 77 78 typename X::value_type value = *it; 79 std::pair<iterator, bool> r1 = x.insert(boost::move(value)); 80 std::pair<typename ordered::iterator, bool> r2 = tracker.insert(*it); 81 82 BOOST_TEST(r1.second == r2.second); 83 BOOST_TEST(*r1.first == *r2.first); 84 85 tracker.compare_key(x, *it); 86 87 if (static_cast<double>(x.size()) <= 88 b * static_cast<double>(old_bucket_count)) 89 BOOST_TEST(x.bucket_count() == old_bucket_count); 90 } 91 92 test::check_equivalent_keys(x); 93 } 94 } 95 96 template <class X> equivalent_insert_tests1(X *,test::random_generator generator)97 void equivalent_insert_tests1(X*, test::random_generator generator) 98 { 99 test::check_instances check_; 100 101 UNORDERED_SUB_TEST( 102 "insert(value) tests for containers with equivalent keys") 103 { 104 X x; 105 test::ordered<X> tracker = test::create_ordered(x); 106 107 test::random_values<X> v(1000, generator); 108 for (typename test::random_values<X>::iterator it = v.begin(); 109 it != v.end(); ++it) { 110 typename X::size_type old_bucket_count = x.bucket_count(); 111 float b = x.max_load_factor(); 112 113 typename X::iterator r1 = x.insert(*it); 114 typename test::ordered<X>::iterator r2 = tracker.insert(*it); 115 116 BOOST_TEST(*r1 == *r2); 117 118 tracker.compare_key(x, *it); 119 120 if (static_cast<double>(x.size()) <= 121 b * static_cast<double>(old_bucket_count)) 122 BOOST_TEST(x.bucket_count() == old_bucket_count); 123 } 124 125 test::check_equivalent_keys(x); 126 } 127 128 UNORDERED_SUB_TEST( 129 "insert(rvalue) tests for containers with equivalent keys") 130 { 131 X x; 132 test::ordered<X> tracker = test::create_ordered(x); 133 134 test::random_values<X> v(1000, generator); 135 for (typename test::random_values<X>::iterator it = v.begin(); 136 it != v.end(); ++it) { 137 typename X::size_type old_bucket_count = x.bucket_count(); 138 float b = x.max_load_factor(); 139 140 typename X::value_type value = *it; 141 typename X::iterator r1 = x.insert(boost::move(value)); 142 typename test::ordered<X>::iterator r2 = tracker.insert(*it); 143 144 BOOST_TEST(*r1 == *r2); 145 146 tracker.compare_key(x, *it); 147 148 if (static_cast<double>(x.size()) <= 149 b * static_cast<double>(old_bucket_count)) 150 BOOST_TEST(x.bucket_count() == old_bucket_count); 151 } 152 153 test::check_equivalent_keys(x); 154 } 155 } 156 insert_tests2(X *,test::random_generator generator)157 template <class X> void insert_tests2(X*, test::random_generator generator) 158 { 159 typedef typename test::ordered<X> tracker_type; 160 typedef typename X::iterator iterator; 161 typedef typename X::const_iterator const_iterator; 162 typedef typename tracker_type::iterator tracker_iterator; 163 164 UNORDERED_SUB_TEST("insert(begin(), value) tests") 165 { 166 test::check_instances check_; 167 168 X x; 169 tracker_type tracker = test::create_ordered(x); 170 171 test::random_values<X> v(1000, generator); 172 for (typename test::random_values<X>::iterator it = v.begin(); 173 it != v.end(); ++it) { 174 typename X::size_type old_bucket_count = x.bucket_count(); 175 float b = x.max_load_factor(); 176 177 iterator r1 = x.insert(x.begin(), *it); 178 tracker_iterator r2 = tracker.insert(tracker.begin(), *it); 179 BOOST_TEST(*r1 == *r2); 180 tracker.compare_key(x, *it); 181 182 if (static_cast<double>(x.size()) <= 183 b * static_cast<double>(old_bucket_count)) 184 BOOST_TEST(x.bucket_count() == old_bucket_count); 185 } 186 187 tracker.compare(x); 188 test::check_equivalent_keys(x); 189 } 190 191 UNORDERED_SUB_TEST("insert(end(), value) tests") 192 { 193 test::check_instances check_; 194 195 X x; 196 X const& x_const = x; 197 tracker_type tracker = test::create_ordered(x); 198 199 test::random_values<X> v(100, generator); 200 for (typename test::random_values<X>::iterator it = v.begin(); 201 it != v.end(); ++it) { 202 typename X::size_type old_bucket_count = x.bucket_count(); 203 float b = x.max_load_factor(); 204 205 const_iterator r1 = x.insert(x_const.end(), *it); 206 tracker_iterator r2 = tracker.insert(tracker.end(), *it); 207 BOOST_TEST(*r1 == *r2); 208 tracker.compare_key(x, *it); 209 210 if (static_cast<double>(x.size()) <= 211 b * static_cast<double>(old_bucket_count)) 212 BOOST_TEST(x.bucket_count() == old_bucket_count); 213 } 214 215 tracker.compare(x); 216 test::check_equivalent_keys(x); 217 } 218 219 UNORDERED_SUB_TEST("insert(pos, value) tests") 220 { 221 test::check_instances check_; 222 223 X x; 224 const_iterator pos = x.begin(); 225 tracker_type tracker = test::create_ordered(x); 226 227 test::random_values<X> v(1000, generator); 228 for (typename test::random_values<X>::iterator it = v.begin(); 229 it != v.end(); ++it) { 230 typename X::size_type old_bucket_count = x.bucket_count(); 231 float b = x.max_load_factor(); 232 233 pos = x.insert(pos, *it); 234 tracker_iterator r2 = tracker.insert(tracker.begin(), *it); 235 BOOST_TEST(*pos == *r2); 236 tracker.compare_key(x, *it); 237 238 if (static_cast<double>(x.size()) <= 239 b * static_cast<double>(old_bucket_count)) 240 BOOST_TEST(x.bucket_count() == old_bucket_count); 241 } 242 243 tracker.compare(x); 244 test::check_equivalent_keys(x); 245 } 246 247 UNORDERED_SUB_TEST("insert(pos, rvalue) tests") 248 { 249 test::check_instances check_; 250 251 X x; 252 const_iterator pos = x.begin(); 253 tracker_type tracker = test::create_ordered(x); 254 255 test::random_values<X> v(1000, generator); 256 for (typename test::random_values<X>::iterator it = v.begin(); 257 it != v.end(); ++it) { 258 typename X::size_type old_bucket_count = x.bucket_count(); 259 float b = x.max_load_factor(); 260 261 typename X::value_type value = *it; 262 pos = x.insert(pos, boost::move(value)); 263 tracker_iterator r2 = tracker.insert(tracker.begin(), *it); 264 BOOST_TEST(*pos == *r2); 265 tracker.compare_key(x, *it); 266 267 if (static_cast<double>(x.size()) <= 268 b * static_cast<double>(old_bucket_count)) 269 BOOST_TEST(x.bucket_count() == old_bucket_count); 270 } 271 272 tracker.compare(x); 273 test::check_equivalent_keys(x); 274 } 275 276 UNORDERED_SUB_TEST("insert single item range tests") 277 { 278 test::check_instances check_; 279 280 X x; 281 tracker_type tracker = test::create_ordered(x); 282 283 test::random_values<X> v(1000, generator); 284 for (typename test::random_values<X>::iterator it = v.begin(); 285 it != v.end(); ++it) { 286 typename X::size_type old_bucket_count = x.bucket_count(); 287 float b = x.max_load_factor(); 288 289 x.insert(it, test::next(it)); 290 tracker.insert(*it); 291 tracker.compare_key(x, *it); 292 293 if (static_cast<double>(x.size()) <= 294 b * static_cast<double>(old_bucket_count)) 295 BOOST_TEST(x.bucket_count() == old_bucket_count); 296 } 297 298 tracker.compare(x); 299 test::check_equivalent_keys(x); 300 } 301 302 UNORDERED_SUB_TEST("insert range tests") 303 { 304 test::check_instances check_; 305 306 X x; 307 308 test::random_values<X> v(1000, generator); 309 x.insert(v.begin(), v.end()); 310 311 test::check_container(x, v); 312 test::check_equivalent_keys(x); 313 } 314 315 UNORDERED_SUB_TEST("insert range with rehash tests") 316 { 317 test::check_instances check_; 318 319 X x; 320 321 test::random_values<X> v(1000, generator); 322 323 x.insert(*v.begin()); 324 x.clear(); 325 326 x.insert(v.begin(), v.end()); 327 328 test::check_container(x, v); 329 test::check_equivalent_keys(x); 330 } 331 332 UNORDERED_SUB_TEST("insert input iterator range tests") 333 { 334 test::check_instances check_; 335 336 X x; 337 338 test::random_values<X> v(1000, generator); 339 typename test::random_values<X>::const_iterator begin = v.begin(), 340 end = v.end(); 341 x.insert(test::input_iterator(begin), test::input_iterator(end)); 342 test::check_container(x, v); 343 344 test::check_equivalent_keys(x); 345 } 346 347 UNORDERED_SUB_TEST("insert copy iterator range tests") 348 { 349 test::check_instances check_; 350 351 X x; 352 353 test::random_values<X> v(1000, generator); 354 x.insert(test::copy_iterator(v.begin()), test::copy_iterator(v.end())); 355 test::check_container(x, v); 356 357 test::check_equivalent_keys(x); 358 } 359 360 UNORDERED_SUB_TEST("insert copy iterator range test 2") 361 { 362 test::check_instances check_; 363 364 X x; 365 366 test::random_values<X> v1(500, generator); 367 test::random_values<X> v2(500, generator); 368 x.insert(test::copy_iterator(v1.begin()), test::copy_iterator(v1.end())); 369 x.insert(test::copy_iterator(v2.begin()), test::copy_iterator(v2.end())); 370 371 test::check_equivalent_keys(x); 372 } 373 374 UNORDERED_SUB_TEST("insert various ranges") 375 { 376 for (int i = 0; i < 100; ++i) { 377 X x; 378 test::ordered<X> tracker = test::create_ordered(x); 379 380 test::random_values<X> v(1000, generator); 381 382 for (typename test::random_values<X>::iterator it = v.begin(); 383 it != v.end();) { 384 typename X::size_type old_bucket_count = x.bucket_count(); 385 float b = x.max_load_factor(); 386 387 typename test::random_values<X>::iterator next = it; 388 for (std::size_t j = test::random_value(20); j > 0; ++j) { 389 ++next; 390 if (next == v.end()) { 391 break; 392 } 393 } 394 395 x.insert(it, next); 396 tracker.insert(it, next); 397 it = next; 398 399 tracker.compare(x); // Slow, but I can't see any other way. 400 401 if (static_cast<double>(x.size()) <= 402 b * static_cast<double>(old_bucket_count)) 403 BOOST_TEST(x.bucket_count() == old_bucket_count); 404 } 405 406 test::check_equivalent_keys(x); 407 } 408 } 409 } 410 411 template <class X> unique_emplace_tests1(X *,test::random_generator generator)412 void unique_emplace_tests1(X*, test::random_generator generator) 413 { 414 typedef typename X::iterator iterator; 415 typedef test::ordered<X> ordered; 416 417 X x; 418 test::ordered<X> tracker = test::create_ordered(x); 419 420 test::random_values<X> v(1000, generator); 421 422 for (typename test::random_values<X>::iterator it = v.begin(); 423 it != v.end(); ++it) { 424 425 typename X::size_type old_bucket_count = x.bucket_count(); 426 float b = x.max_load_factor(); 427 428 std::pair<iterator, bool> r1 = x.emplace(*it); 429 std::pair<typename ordered::iterator, bool> r2 = tracker.insert(*it); 430 431 BOOST_TEST(r1.second == r2.second); 432 BOOST_TEST(*r1.first == *r2.first); 433 434 tracker.compare_key(x, *it); 435 436 if (static_cast<double>(x.size()) <= 437 b * static_cast<double>(old_bucket_count)) 438 BOOST_TEST(x.bucket_count() == old_bucket_count); 439 } 440 441 tracker.compare(x); 442 test::check_equivalent_keys(x); 443 } 444 445 template <class X> equivalent_emplace_tests1(X *,test::random_generator generator)446 void equivalent_emplace_tests1(X*, test::random_generator generator) 447 { 448 X x; 449 test::ordered<X> tracker = test::create_ordered(x); 450 451 test::random_values<X> v(1000, generator); 452 for (typename test::random_values<X>::iterator it = v.begin(); 453 it != v.end(); ++it) { 454 typename X::size_type old_bucket_count = x.bucket_count(); 455 float b = x.max_load_factor(); 456 457 typename X::iterator r1 = x.emplace(*it); 458 typename test::ordered<X>::iterator r2 = tracker.insert(*it); 459 460 BOOST_TEST(*r1 == *r2); 461 462 tracker.compare_key(x, *it); 463 464 if (static_cast<double>(x.size()) <= 465 b * static_cast<double>(old_bucket_count)) 466 BOOST_TEST(x.bucket_count() == old_bucket_count); 467 } 468 469 tracker.compare(x); 470 test::check_equivalent_keys(x); 471 } 472 473 template <class X> move_emplace_tests(X *,test::random_generator generator)474 void move_emplace_tests(X*, test::random_generator generator) 475 { 476 X x; 477 test::ordered<X> tracker = test::create_ordered(x); 478 479 test::random_values<X> v(1000, generator); 480 481 for (typename test::random_values<X>::iterator it = v.begin(); 482 it != v.end(); ++it) { 483 484 typename X::size_type old_bucket_count = x.bucket_count(); 485 float b = x.max_load_factor(); 486 487 typename X::value_type value = *it; 488 x.emplace(boost::move(value)); 489 tracker.insert(*it); 490 tracker.compare_key(x, *it); 491 492 if (static_cast<double>(x.size()) <= 493 b * static_cast<double>(old_bucket_count)) 494 BOOST_TEST(x.bucket_count() == old_bucket_count); 495 } 496 497 tracker.compare(x); 498 test::check_equivalent_keys(x); 499 } 500 default_emplace_tests(X *,test::random_generator)501 template <class X> void default_emplace_tests(X*, test::random_generator) 502 { 503 #if !BOOST_UNORDERED_SUN_WORKAROUNDS1 504 bool is_unique = test::has_unique_keys<X>::value; 505 506 X x; 507 508 x.emplace(); 509 BOOST_TEST(x.size() == 1); 510 x.emplace(); 511 BOOST_TEST(x.size() == (is_unique ? 1u : 2u)); 512 x.emplace(); 513 BOOST_TEST(x.size() == (is_unique ? 1u : 3u)); 514 515 typename X::value_type y; 516 BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 3u)); 517 BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y); 518 519 x.emplace(y); 520 BOOST_TEST(x.size() == (is_unique ? 1u : 4u)); 521 BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 4u)); 522 BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y); 523 524 x.clear(); 525 BOOST_TEST(x.empty()); 526 x.emplace(y); 527 BOOST_TEST(x.size() == 1); 528 x.emplace(y); 529 BOOST_TEST(x.size() == (is_unique ? 1u : 2u)); 530 531 BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 2u)); 532 BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y); 533 #endif 534 } 535 map_tests(X *,test::random_generator generator)536 template <class X> void map_tests(X*, test::random_generator generator) 537 { 538 X x; 539 test::ordered<X> tracker = test::create_ordered(x); 540 541 test::random_values<X> v(1000, generator); 542 for (typename test::random_values<X>::iterator it = v.begin(); 543 it != v.end(); ++it) { 544 typename X::size_type old_bucket_count = x.bucket_count(); 545 float b = x.max_load_factor(); 546 547 x[it->first] = it->second; 548 tracker[it->first] = it->second; 549 550 tracker.compare_key(x, *it); 551 552 if (static_cast<double>(x.size()) <= 553 b * static_cast<double>(old_bucket_count)) 554 BOOST_TEST(x.bucket_count() == old_bucket_count); 555 } 556 557 tracker.compare(x); 558 test::check_equivalent_keys(x); 559 } 560 map_tests2(X *,test::random_generator generator)561 template <class X> void map_tests2(X*, test::random_generator generator) 562 { 563 typedef typename X::iterator iterator; 564 565 UNORDERED_SUB_TEST("insert_or_assign") 566 { 567 test::check_instances check_; 568 569 X x; 570 test::ordered<X> tracker = test::create_ordered(x); 571 572 test::random_values<X> v(1000, generator); 573 for (typename test::random_values<X>::iterator it = v.begin(); 574 it != v.end(); ++it) { 575 typename X::size_type old_bucket_count = x.bucket_count(); 576 float b = x.max_load_factor(); 577 578 std::pair<iterator, bool> r = x.insert_or_assign(it->first, it->second); 579 BOOST_TEST(*r.first == *it); 580 581 tracker[it->first] = it->second; 582 tracker.compare_key(x, *it); 583 584 if (static_cast<double>(x.size()) < 585 b * static_cast<double>(old_bucket_count)) 586 BOOST_TEST(x.bucket_count() == old_bucket_count); 587 } 588 589 tracker.compare(x); 590 test::check_equivalent_keys(x); 591 } 592 593 UNORDERED_SUB_TEST("insert_or_assign(begin)") 594 { 595 test::check_instances check_; 596 597 X x; 598 test::ordered<X> tracker = test::create_ordered(x); 599 600 test::random_values<X> v(1000, generator); 601 for (typename test::random_values<X>::iterator it = v.begin(); 602 it != v.end(); ++it) { 603 typename X::size_type old_bucket_count = x.bucket_count(); 604 float b = x.max_load_factor(); 605 606 iterator r = x.insert_or_assign(x.begin(), it->first, it->second); 607 BOOST_TEST(*r == *it); 608 609 tracker[it->first] = it->second; 610 tracker.compare_key(x, *it); 611 612 if (static_cast<double>(x.size()) < 613 b * static_cast<double>(old_bucket_count)) 614 BOOST_TEST(x.bucket_count() == old_bucket_count); 615 } 616 617 tracker.compare(x); 618 test::check_equivalent_keys(x); 619 } 620 621 UNORDERED_SUB_TEST("insert_or_assign(end)") 622 { 623 test::check_instances check_; 624 625 X x; 626 test::ordered<X> tracker = test::create_ordered(x); 627 628 test::random_values<X> v(1000, generator); 629 for (typename test::random_values<X>::iterator it = v.begin(); 630 it != v.end(); ++it) { 631 typename X::size_type old_bucket_count = x.bucket_count(); 632 float b = x.max_load_factor(); 633 634 iterator r = x.insert_or_assign(x.end(), it->first, it->second); 635 BOOST_TEST(*r == *it); 636 637 tracker[it->first] = it->second; 638 tracker.compare_key(x, *it); 639 640 if (static_cast<double>(x.size()) < 641 b * static_cast<double>(old_bucket_count)) 642 BOOST_TEST(x.bucket_count() == old_bucket_count); 643 } 644 645 tracker.compare(x); 646 test::check_equivalent_keys(x); 647 } 648 649 UNORDERED_SUB_TEST("insert_or_assign(last)") 650 { 651 test::check_instances check_; 652 653 X x; 654 test::ordered<X> tracker = test::create_ordered(x); 655 iterator last = x.begin(); 656 657 test::random_values<X> v(1000, generator); 658 for (typename test::random_values<X>::iterator it = v.begin(); 659 it != v.end(); ++it) { 660 typename X::size_type old_bucket_count = x.bucket_count(); 661 float b = x.max_load_factor(); 662 663 iterator r = x.insert_or_assign(last, it->first, it->second); 664 BOOST_TEST(*r == *it); 665 666 tracker[it->first] = it->second; 667 tracker.compare_key(x, *it); 668 669 if (static_cast<double>(x.size()) < 670 b * static_cast<double>(old_bucket_count)) 671 BOOST_TEST(x.bucket_count() == old_bucket_count); 672 673 last = r; 674 } 675 676 tracker.compare(x); 677 test::check_equivalent_keys(x); 678 } 679 } 680 681 template <class X> try_emplace_tests(X *,test::random_generator generator)682 void try_emplace_tests(X*, test::random_generator generator) 683 { 684 typedef typename X::iterator iterator; 685 686 UNORDERED_SUB_TEST("try_emplace(key, value)") 687 { 688 test::check_instances check_; 689 690 X x; 691 test::ordered<X> tracker = test::create_ordered(x); 692 693 test::random_values<X> v(1000, generator); 694 for (typename test::random_values<X>::iterator it = v.begin(); 695 it != v.end(); ++it) { 696 typename X::size_type old_bucket_count = x.bucket_count(); 697 float b = x.max_load_factor(); 698 699 iterator pos = x.find(it->first); 700 bool found = pos != x.end(); 701 702 std::pair<typename X::iterator, bool> r = 703 x.try_emplace(it->first, it->second); 704 if (found) { 705 BOOST_TEST(pos == r.first); 706 BOOST_TEST(!r.second); 707 } else { 708 BOOST_TEST(r.second); 709 } 710 BOOST_TEST_EQ(r.first->first, it->first); 711 BOOST_TEST_EQ(r.first->second, it->second); 712 713 tracker.insert(*it); 714 tracker.compare_key(x, *it); 715 716 if (static_cast<double>(x.size()) < 717 b * static_cast<double>(old_bucket_count)) 718 BOOST_TEST(x.bucket_count() == old_bucket_count); 719 } 720 721 test::check_equivalent_keys(x); 722 } 723 724 typedef typename X::iterator iterator; 725 726 UNORDERED_SUB_TEST("try_emplace(begin(), key, value)") 727 { 728 test::check_instances check_; 729 730 X x; 731 test::ordered<X> tracker = test::create_ordered(x); 732 733 test::random_values<X> v(1000, generator); 734 for (typename test::random_values<X>::iterator it = v.begin(); 735 it != v.end(); ++it) { 736 typename X::size_type old_bucket_count = x.bucket_count(); 737 float b = x.max_load_factor(); 738 739 iterator pos = x.find(it->first); 740 bool found = pos != x.end(); 741 742 typename X::iterator r = 743 x.try_emplace(r.begin(), it->first, it->second); 744 if (found) { 745 BOOST_TEST(pos == r); 746 } 747 BOOST_TEST_EQ(r->first, it->first); 748 BOOST_TEST_EQ(r->second, it->second); 749 750 tracker.insert(*it); 751 tracker.compare_key(x, *it); 752 753 if (static_cast<double>(x.size()) < 754 b * static_cast<double>(old_bucket_count)) 755 BOOST_TEST(x.bucket_count() == old_bucket_count); 756 } 757 758 test::check_equivalent_keys(x); 759 } 760 761 typedef typename X::iterator iterator; 762 763 UNORDERED_SUB_TEST("try_emplace(end(), key, value)") 764 { 765 test::check_instances check_; 766 767 X x; 768 test::ordered<X> tracker = test::create_ordered(x); 769 770 test::random_values<X> v(1000, generator); 771 for (typename test::random_values<X>::iterator it = v.begin(); 772 it != v.end(); ++it) { 773 typename X::size_type old_bucket_count = x.bucket_count(); 774 float b = x.max_load_factor(); 775 776 iterator pos = x.find(it->first); 777 bool found = pos != x.end(); 778 779 typename X::iterator r = x.try_emplace(r.end(), it->first, it->second); 780 if (found) { 781 BOOST_TEST(pos == r); 782 } 783 BOOST_TEST_EQ(r->first, it->first); 784 BOOST_TEST_EQ(r->second, it->second); 785 786 tracker.insert(*it); 787 tracker.compare_key(x, *it); 788 789 if (static_cast<double>(x.size()) < 790 b * static_cast<double>(old_bucket_count)) 791 BOOST_TEST(x.bucket_count() == old_bucket_count); 792 } 793 794 test::check_equivalent_keys(x); 795 } 796 797 typedef typename X::iterator iterator; 798 799 UNORDERED_SUB_TEST("try_emplace(pos, key, value)") 800 { 801 test::check_instances check_; 802 803 X x; 804 test::ordered<X> tracker = test::create_ordered(x); 805 806 test::random_values<X> v(1000, generator); 807 for (typename test::random_values<X>::iterator it = v.begin(); 808 it != v.end(); ++it) { 809 typename X::size_type old_bucket_count = x.bucket_count(); 810 float b = x.max_load_factor(); 811 812 iterator pos = x.find(it->first); 813 bool found = pos != x.end(); 814 815 typename X::iterator r = x.try_emplace(pos, it->first, it->second); 816 if (found) { 817 BOOST_TEST(pos == r); 818 } 819 BOOST_TEST_EQ(r->first, it->first); 820 BOOST_TEST_EQ(r->second, it->second); 821 822 tracker.insert(*it); 823 tracker.compare_key(x, *it); 824 825 if (static_cast<double>(x.size()) < 826 b * static_cast<double>(old_bucket_count)) 827 BOOST_TEST(x.bucket_count() == old_bucket_count); 828 } 829 830 test::check_equivalent_keys(x); 831 } 832 } 833 834 // Some tests for when the range's value type doesn't match the container's 835 // value type. 836 837 template <class X> map_insert_range_test1(X *,test::random_generator generator)838 void map_insert_range_test1(X*, test::random_generator generator) 839 { 840 test::check_instances check_; 841 842 typedef test::list< 843 std::pair<typename X::key_type, typename X::mapped_type> > 844 list; 845 test::random_values<X> v(1000, generator); 846 list l(v.begin(), v.end()); 847 848 X x; 849 x.insert(l.begin(), l.end()); 850 851 test::check_equivalent_keys(x); 852 } 853 854 template <class X> map_insert_range_test2(X *,test::random_generator generator)855 void map_insert_range_test2(X*, test::random_generator generator) 856 { 857 test::check_instances check_; 858 859 typedef test::list< 860 std::pair<typename X::key_type const, test::implicitly_convertible> > 861 list; 862 test::random_values< 863 boost::unordered_map<typename X::key_type, test::implicitly_convertible> > 864 v(1000, generator); 865 list l(v.begin(), v.end()); 866 867 X x; 868 x.insert(l.begin(), l.end()); 869 870 test::check_equivalent_keys(x); 871 } 872 873 boost::unordered_set<test::movable, test::hash, test::equal_to, 874 std::allocator<test::movable> >* test_set_std_alloc; 875 boost::unordered_multimap<test::object, test::object, test::hash, 876 test::equal_to, std::allocator<test::object> >* test_multimap_std_alloc; 877 878 boost::unordered_set<test::object, test::hash, test::equal_to, 879 test::allocator1<test::object> >* test_set; 880 boost::unordered_multiset<test::movable, test::hash, test::equal_to, 881 test::allocator2<test::movable> >* test_multiset; 882 boost::unordered_map<test::movable, test::movable, test::hash, test::equal_to, 883 test::allocator2<test::movable> >* test_map; 884 boost::unordered_multimap<test::object, test::object, test::hash, 885 test::equal_to, test::allocator1<test::object> >* test_multimap; 886 887 using test::default_generator; 888 using test::generate_collisions; 889 using test::limited_range; 890 891 UNORDERED_TEST(unique_insert_tests1, 892 ((test_set_std_alloc)(test_set)(test_map))( 893 (default_generator)(generate_collisions)(limited_range))) 894 895 UNORDERED_TEST(equivalent_insert_tests1, 896 ((test_multimap_std_alloc)(test_multiset)(test_multimap))( 897 (default_generator)(generate_collisions)(limited_range))) 898 899 UNORDERED_TEST(insert_tests2, 900 ((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)( 901 test_multimap))((default_generator)(generate_collisions)(limited_range))) 902 903 UNORDERED_TEST(unique_emplace_tests1, 904 ((test_set_std_alloc)(test_set)(test_map))( 905 (default_generator)(generate_collisions)(limited_range))) 906 907 UNORDERED_TEST(equivalent_emplace_tests1, 908 ((test_multimap_std_alloc)(test_multiset)(test_multimap))( 909 (default_generator)(generate_collisions)(limited_range))) 910 911 UNORDERED_TEST(move_emplace_tests, 912 ((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)( 913 test_multiset)(test_multimap))( 914 (default_generator)(generate_collisions)(limited_range))) 915 916 UNORDERED_TEST(default_emplace_tests, 917 ((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)( 918 test_multiset)(test_multimap))( 919 (default_generator)(generate_collisions)(limited_range))) 920 921 UNORDERED_TEST(map_tests, 922 ((test_map))((default_generator)(generate_collisions)(limited_range))) 923 924 UNORDERED_TEST( 925 map_tests2, ((test_map))((default_generator)(generate_collisions))) 926 927 UNORDERED_TEST(map_insert_range_test1, 928 ((test_multimap_std_alloc)(test_map)(test_multimap))( 929 (default_generator)(generate_collisions)(limited_range))) 930 931 UNORDERED_TEST(map_insert_range_test2, 932 ((test_multimap_std_alloc)(test_map)(test_multimap))( 933 (default_generator)(generate_collisions)(limited_range))) 934 935 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 936 937 struct initialize_from_two_ints 938 { 939 int a, b; 940 hash_value(initialize_from_two_ints const & x)941 friend std::size_t hash_value(initialize_from_two_ints const& x) 942 { 943 return static_cast<std::size_t>(x.a + x.b); 944 } 945 operator ==insert_tests::initialize_from_two_ints946 bool operator==(initialize_from_two_ints const& x) const 947 { 948 return a == x.a && b == x.b; 949 } 950 }; 951 UNORDERED_AUTO_TEST(insert_initializer_list_set)952 UNORDERED_AUTO_TEST (insert_initializer_list_set) { 953 boost::unordered_set<int> set; 954 set.insert({1, 2, 3, 1}); 955 BOOST_TEST_EQ(set.size(), 3u); 956 BOOST_TEST(set.find(1) != set.end()); 957 BOOST_TEST(set.find(4) == set.end()); 958 959 boost::unordered_set<initialize_from_two_ints> set2; 960 961 #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)) 962 set2.insert({{1, 2}}); 963 #else 964 set2.insert({1, 2}); 965 #endif 966 BOOST_TEST(set2.size() == 1); 967 BOOST_TEST(set2.find({1, 2}) != set2.end()); 968 BOOST_TEST(set2.find({2, 1}) == set2.end()); 969 970 set2.insert({{3, 4}, {5, 6}, {7, 8}}); 971 BOOST_TEST(set2.size() == 4); 972 BOOST_TEST(set2.find({1, 2}) != set2.end()); 973 BOOST_TEST(set2.find({3, 4}) != set2.end()); 974 BOOST_TEST(set2.find({5, 6}) != set2.end()); 975 BOOST_TEST(set2.find({7, 8}) != set2.end()); 976 BOOST_TEST(set2.find({8, 7}) == set2.end()); 977 978 set2.insert({{2, 1}, {3, 4}}); 979 BOOST_TEST(set2.size() == 5); 980 BOOST_TEST(set2.find({1, 2}) != set2.end()); 981 BOOST_TEST(set2.find({2, 1}) != set2.end()); 982 BOOST_TEST(set2.find({3, 4}) != set2.end()); 983 BOOST_TEST(set2.find({5, 6}) != set2.end()); 984 BOOST_TEST(set2.find({7, 8}) != set2.end()); 985 BOOST_TEST(set2.find({8, 7}) == set2.end()); 986 } 987 988 #if !BOOST_WORKAROUND(BOOST_MSVC, == 1800) 989 UNORDERED_AUTO_TEST(insert_initializer_list_multiset)990 UNORDERED_AUTO_TEST (insert_initializer_list_multiset) { 991 boost::unordered_multiset<std::string> multiset; 992 // multiset.insert({}); 993 BOOST_TEST(multiset.empty()); 994 multiset.insert({"a"}); 995 BOOST_TEST_EQ(multiset.size(), 1u); 996 BOOST_TEST(multiset.find("a") != multiset.end()); 997 BOOST_TEST(multiset.find("b") == multiset.end()); 998 multiset.insert({"a", "b"}); 999 BOOST_TEST(multiset.size() == 3); 1000 BOOST_TEST_EQ(multiset.count("a"), 2u); 1001 BOOST_TEST_EQ(multiset.count("b"), 1u); 1002 BOOST_TEST_EQ(multiset.count("c"), 0u); 1003 } 1004 1005 #endif 1006 UNORDERED_AUTO_TEST(insert_initializer_list_map)1007 UNORDERED_AUTO_TEST (insert_initializer_list_map) { 1008 boost::unordered_map<std::string, std::string> map; 1009 // map.insert({}); 1010 BOOST_TEST(map.empty()); 1011 map.insert({{"a", "b"}, {"a", "b"}, {"d", ""}}); 1012 BOOST_TEST_EQ(map.size(), 2u); 1013 } 1014 UNORDERED_AUTO_TEST(insert_initializer_list_multimap)1015 UNORDERED_AUTO_TEST (insert_initializer_list_multimap) { 1016 boost::unordered_multimap<std::string, std::string> multimap; 1017 // multimap.insert({}); 1018 BOOST_TEST(multimap.empty()); 1019 multimap.insert({{"a", "b"}, {"a", "b"}, {"d", ""}}); 1020 BOOST_TEST_EQ(multimap.size(), 3u); 1021 BOOST_TEST_EQ(multimap.count("a"), 2u); 1022 } 1023 1024 #endif 1025 1026 struct overloaded_constructor 1027 { overloaded_constructorinsert_tests::overloaded_constructor1028 overloaded_constructor(int x1_ = 1, int x2_ = 2, int x3_ = 3, int x4_ = 4) 1029 : x1(x1_), x2(x2_), x3(x3_), x4(x4_) 1030 { 1031 } 1032 1033 int x1, x2, x3, x4; 1034 operator ==insert_tests::overloaded_constructor1035 bool operator==(overloaded_constructor const& rhs) const 1036 { 1037 return x1 == rhs.x1 && x2 == rhs.x2 && x3 == rhs.x3 && x4 == rhs.x4; 1038 } 1039 hash_value(overloaded_constructor const & x)1040 friend std::size_t hash_value(overloaded_constructor const& x) 1041 { 1042 std::size_t hash = 0; 1043 boost::hash_combine(hash, x.x1); 1044 boost::hash_combine(hash, x.x2); 1045 boost::hash_combine(hash, x.x3); 1046 boost::hash_combine(hash, x.x4); 1047 return hash; 1048 } 1049 }; 1050 UNORDERED_AUTO_TEST(map_emplace_test)1051 UNORDERED_AUTO_TEST (map_emplace_test) { 1052 { 1053 boost::unordered_map<int, overloaded_constructor, test::hash, 1054 test::equal_to, 1055 test::allocator1<std::pair<int const, overloaded_constructor> > > 1056 x; 1057 1058 #if !BOOST_UNORDERED_SUN_WORKAROUNDS1 1059 x.emplace(); 1060 BOOST_TEST( 1061 x.find(0) != x.end() && x.find(0)->second == overloaded_constructor()); 1062 #endif 1063 1064 x.emplace(2, 3); 1065 BOOST_TEST( 1066 x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3)); 1067 1068 x.try_emplace(5); 1069 BOOST_TEST( 1070 x.find(5) != x.end() && x.find(5)->second == overloaded_constructor()); 1071 } 1072 1073 { 1074 boost::unordered_multimap<int, overloaded_constructor, test::hash, 1075 test::equal_to, 1076 test::allocator1<std::pair<int const, overloaded_constructor> > > 1077 x; 1078 1079 #if !BOOST_UNORDERED_SUN_WORKAROUNDS1 1080 x.emplace(); 1081 BOOST_TEST( 1082 x.find(0) != x.end() && x.find(0)->second == overloaded_constructor()); 1083 #endif 1084 1085 x.emplace(2, 3); 1086 BOOST_TEST( 1087 x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3)); 1088 } 1089 } 1090 UNORDERED_AUTO_TEST(set_emplace_test)1091 UNORDERED_AUTO_TEST (set_emplace_test) { 1092 boost::unordered_set<overloaded_constructor> x; 1093 overloaded_constructor check; 1094 1095 #if !BOOST_UNORDERED_SUN_WORKAROUNDS1 1096 x.emplace(); 1097 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1098 #endif 1099 1100 x.clear(); 1101 x.emplace(1); 1102 check = overloaded_constructor(1); 1103 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1104 1105 x.clear(); 1106 x.emplace(2, 3); 1107 check = overloaded_constructor(2, 3); 1108 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1109 1110 x.clear(); 1111 x.emplace(4, 5, 6); 1112 check = overloaded_constructor(4, 5, 6); 1113 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1114 1115 x.clear(); 1116 x.emplace(7, 8, 9, 10); 1117 check = overloaded_constructor(7, 8, 9, 10); 1118 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1119 } 1120 1121 struct derived_from_piecewise_construct_t 1122 : boost::unordered::piecewise_construct_t 1123 { 1124 }; 1125 piecewise_rvalue()1126 derived_from_piecewise_construct_t piecewise_rvalue() 1127 { 1128 return derived_from_piecewise_construct_t(); 1129 } 1130 1131 struct convertible_to_piecewise 1132 { operator boost::unordered::piecewise_construct_tinsert_tests::convertible_to_piecewise1133 operator boost::unordered::piecewise_construct_t() const 1134 { 1135 return boost::unordered::piecewise_construct; 1136 } 1137 }; 1138 UNORDERED_AUTO_TEST(map_emplace_test2)1139 UNORDERED_AUTO_TEST (map_emplace_test2) { 1140 // Emulating piecewise construction with boost::tuple bypasses the 1141 // allocator's construct method, but still uses test destroy method. 1142 test::detail::disable_construction_tracking _scoped; 1143 1144 { 1145 boost::unordered_map<overloaded_constructor, overloaded_constructor, 1146 boost::hash<overloaded_constructor>, 1147 std::equal_to<overloaded_constructor>, 1148 test::allocator1< 1149 std::pair<overloaded_constructor const, overloaded_constructor> > > 1150 x; 1151 1152 x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), 1153 boost::make_tuple()); 1154 BOOST_TEST( 1155 x.find(overloaded_constructor()) != x.end() && 1156 x.find(overloaded_constructor())->second == overloaded_constructor()); 1157 1158 x.emplace( 1159 convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple()); 1160 BOOST_TEST( 1161 x.find(overloaded_constructor(1)) != x.end() && 1162 x.find(overloaded_constructor(1))->second == overloaded_constructor()); 1163 1164 x.emplace(piecewise_rvalue(), boost::make_tuple(2, 3), 1165 boost::make_tuple(4, 5, 6)); 1166 BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && 1167 x.find(overloaded_constructor(2, 3))->second == 1168 overloaded_constructor(4, 5, 6)); 1169 1170 derived_from_piecewise_construct_t d; 1171 x.emplace(d, boost::make_tuple(9, 3, 1), boost::make_tuple(10)); 1172 BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() && 1173 x.find(overloaded_constructor(9, 3, 1))->second == 1174 overloaded_constructor(10)); 1175 1176 x.clear(); 1177 1178 x.try_emplace(overloaded_constructor()); 1179 BOOST_TEST( 1180 x.find(overloaded_constructor()) != x.end() && 1181 x.find(overloaded_constructor())->second == overloaded_constructor()); 1182 1183 x.try_emplace(1); 1184 BOOST_TEST( 1185 x.find(overloaded_constructor(1)) != x.end() && 1186 x.find(overloaded_constructor(1))->second == overloaded_constructor()); 1187 1188 x.try_emplace(overloaded_constructor(2, 3), 4, 5, 6); 1189 BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && 1190 x.find(overloaded_constructor(2, 3))->second == 1191 overloaded_constructor(4, 5, 6)); 1192 1193 x.clear(); 1194 1195 x.try_emplace(x.begin(), overloaded_constructor()); 1196 BOOST_TEST( 1197 x.find(overloaded_constructor()) != x.end() && 1198 x.find(overloaded_constructor())->second == overloaded_constructor()); 1199 1200 x.try_emplace(x.end(), 1); 1201 BOOST_TEST( 1202 x.find(overloaded_constructor(1)) != x.end() && 1203 x.find(overloaded_constructor(1))->second == overloaded_constructor()); 1204 1205 x.try_emplace(x.begin(), overloaded_constructor(2, 3), 4, 5, 6); 1206 BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && 1207 x.find(overloaded_constructor(2, 3))->second == 1208 overloaded_constructor(4, 5, 6)); 1209 } 1210 1211 { 1212 boost::unordered_multimap<overloaded_constructor, overloaded_constructor, 1213 boost::hash<overloaded_constructor>, 1214 std::equal_to<overloaded_constructor>, 1215 test::allocator1< 1216 std::pair<overloaded_constructor const, overloaded_constructor> > > 1217 x; 1218 1219 x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), 1220 boost::make_tuple()); 1221 BOOST_TEST( 1222 x.find(overloaded_constructor()) != x.end() && 1223 x.find(overloaded_constructor())->second == overloaded_constructor()); 1224 1225 x.emplace( 1226 convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple()); 1227 BOOST_TEST( 1228 x.find(overloaded_constructor(1)) != x.end() && 1229 x.find(overloaded_constructor(1))->second == overloaded_constructor()); 1230 1231 x.emplace(piecewise_rvalue(), boost::make_tuple(2, 3), 1232 boost::make_tuple(4, 5, 6)); 1233 BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && 1234 x.find(overloaded_constructor(2, 3))->second == 1235 overloaded_constructor(4, 5, 6)); 1236 1237 derived_from_piecewise_construct_t d; 1238 x.emplace(d, boost::make_tuple(9, 3, 1), boost::make_tuple(10)); 1239 BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() && 1240 x.find(overloaded_constructor(9, 3, 1))->second == 1241 overloaded_constructor(10)); 1242 } 1243 } 1244 UNORDERED_AUTO_TEST(set_emplace_test2)1245 UNORDERED_AUTO_TEST (set_emplace_test2) { 1246 boost::unordered_set< 1247 std::pair<overloaded_constructor, overloaded_constructor> > 1248 x; 1249 std::pair<overloaded_constructor, overloaded_constructor> check; 1250 1251 x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), 1252 boost::make_tuple()); 1253 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1254 1255 x.clear(); 1256 x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1), 1257 boost::make_tuple(2, 3)); 1258 check = 1259 std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3)); 1260 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1261 } 1262 1263 // Use the preprocessor to generate tests using different combinations of 1264 // boost/std piecewise_construct_t/tuple. 1265 1266 #define PIECEWISE_TEST_NAME boost_tuple_piecewise_tests 1267 #define PIECEWISE_NAMESPACE boost::unordered 1268 #define TUPLE_NAMESPACE boost 1269 #define EMULATING_PIECEWISE_CONSTRUCTION 1 1270 #include "./insert_tests.cpp" 1271 1272 #if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1273 1274 #define PIECEWISE_TEST_NAME boost_tuple_std_piecewise_tests 1275 #define PIECEWISE_NAMESPACE std 1276 #define TUPLE_NAMESPACE boost 1277 #define EMULATING_PIECEWISE_CONSTRUCTION 1 1278 #include "./insert_tests.cpp" 1279 1280 #endif 1281 1282 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) 1283 1284 #define PIECEWISE_TEST_NAME std_tuple_boost_piecewise_tests 1285 #define PIECEWISE_NAMESPACE boost::unordered 1286 #define TUPLE_NAMESPACE std 1287 #define EMULATING_PIECEWISE_CONSTRUCTION 0 1288 #include "./insert_tests.cpp" 1289 1290 #endif 1291 1292 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \ 1293 BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1294 1295 #define PIECEWISE_TEST_NAME std_piecewise_tests 1296 #define PIECEWISE_NAMESPACE std 1297 #define TUPLE_NAMESPACE std 1298 #define EMULATING_PIECEWISE_CONSTRUCTION 0 1299 #include "./insert_tests.cpp" 1300 1301 #endif 1302 } 1303 1304 RUN_TESTS_QUIET() 1305 1306 #else // PIECEWISE_TEST_NAME 1307 1308 UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) { 1309 #if EMULATING_PIECEWISE_CONSTRUCTION 1310 test::detail::disable_construction_tracking _scoped; 1311 #endif 1312 1313 { 1314 boost::unordered_map<overloaded_constructor, overloaded_constructor, 1315 boost::hash<overloaded_constructor>, 1316 std::equal_to<overloaded_constructor>, 1317 test::allocator1< 1318 std::pair<overloaded_constructor const, overloaded_constructor> > > 1319 x; 1320 1321 x.emplace(PIECEWISE_NAMESPACE::piecewise_construct, 1322 TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple()); 1323 BOOST_TEST( 1324 x.find(overloaded_constructor()) != x.end() && 1325 x.find(overloaded_constructor())->second == overloaded_constructor()); 1326 1327 x.emplace(convertible_to_piecewise(), TUPLE_NAMESPACE::make_tuple(1), 1328 TUPLE_NAMESPACE::make_tuple()); 1329 BOOST_TEST( 1330 x.find(overloaded_constructor(1)) != x.end() && 1331 x.find(overloaded_constructor(1))->second == overloaded_constructor()); 1332 1333 x.emplace(piecewise_rvalue(), TUPLE_NAMESPACE::make_tuple(2, 3), 1334 TUPLE_NAMESPACE::make_tuple(4, 5, 6)); 1335 BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && 1336 x.find(overloaded_constructor(2, 3))->second == 1337 overloaded_constructor(4, 5, 6)); 1338 1339 derived_from_piecewise_construct_t d; 1340 x.emplace( 1341 d, TUPLE_NAMESPACE::make_tuple(9, 3, 1), TUPLE_NAMESPACE::make_tuple(10)); 1342 BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() && 1343 x.find(overloaded_constructor(9, 3, 1))->second == 1344 overloaded_constructor(10)); 1345 1346 x.clear(); 1347 1348 x.try_emplace(overloaded_constructor()); 1349 BOOST_TEST( 1350 x.find(overloaded_constructor()) != x.end() && 1351 x.find(overloaded_constructor())->second == overloaded_constructor()); 1352 1353 x.try_emplace(1); 1354 BOOST_TEST( 1355 x.find(overloaded_constructor(1)) != x.end() && 1356 x.find(overloaded_constructor(1))->second == overloaded_constructor()); 1357 1358 x.try_emplace(overloaded_constructor(2, 3), 4, 5, 6); 1359 BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && 1360 x.find(overloaded_constructor(2, 3))->second == 1361 overloaded_constructor(4, 5, 6)); 1362 } 1363 { 1364 boost::unordered_multimap<overloaded_constructor, overloaded_constructor, 1365 boost::hash<overloaded_constructor>, 1366 std::equal_to<overloaded_constructor>, 1367 test::allocator1< 1368 std::pair<overloaded_constructor const, overloaded_constructor> > > 1369 x; 1370 1371 x.emplace(PIECEWISE_NAMESPACE::piecewise_construct, 1372 TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple()); 1373 BOOST_TEST( 1374 x.find(overloaded_constructor()) != x.end() && 1375 x.find(overloaded_constructor())->second == overloaded_constructor()); 1376 1377 x.emplace(convertible_to_piecewise(), TUPLE_NAMESPACE::make_tuple(1), 1378 TUPLE_NAMESPACE::make_tuple()); 1379 BOOST_TEST( 1380 x.find(overloaded_constructor(1)) != x.end() && 1381 x.find(overloaded_constructor(1))->second == overloaded_constructor()); 1382 1383 x.emplace(piecewise_rvalue(), TUPLE_NAMESPACE::make_tuple(2, 3), 1384 TUPLE_NAMESPACE::make_tuple(4, 5, 6)); 1385 BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && 1386 x.find(overloaded_constructor(2, 3))->second == 1387 overloaded_constructor(4, 5, 6)); 1388 1389 derived_from_piecewise_construct_t d; 1390 x.emplace( 1391 d, TUPLE_NAMESPACE::make_tuple(9, 3, 1), TUPLE_NAMESPACE::make_tuple(10)); 1392 BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() && 1393 x.find(overloaded_constructor(9, 3, 1))->second == 1394 overloaded_constructor(10)); 1395 } 1396 } 1397 1398 UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) { 1399 #if EMULATING_PIECEWISE_CONSTRUCTION 1400 test::detail::disable_construction_tracking _scoped; 1401 #endif 1402 1403 boost::unordered_set< 1404 std::pair<overloaded_constructor, overloaded_constructor> > 1405 x; 1406 std::pair<overloaded_constructor, overloaded_constructor> check; 1407 1408 x.emplace(PIECEWISE_NAMESPACE::piecewise_construct, 1409 TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple()); 1410 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1411 1412 x.clear(); 1413 x.emplace(PIECEWISE_NAMESPACE::piecewise_construct, 1414 TUPLE_NAMESPACE::make_tuple(1), TUPLE_NAMESPACE::make_tuple(2, 3)); 1415 check = 1416 std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3)); 1417 BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); 1418 } 1419 1420 #undef PIECEWISE_TEST_NAME 1421 #undef PIECEWISE_NAMESPACE 1422 #undef TUPLE_NAMESPACE 1423 #undef EMULATING_PIECEWISE_CONSTRUCTION 1424 1425 #endif 1426