1 //===- llvm/unittest/ADT/SmallVectorTest.cpp ------------------------------===// 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 // SmallVector unit tests. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ADT/SmallVector.h" 14 #include "llvm/ADT/ArrayRef.h" 15 #include "llvm/Support/Compiler.h" 16 #include "gtest/gtest.h" 17 #include <list> 18 #include <stdarg.h> 19 20 using namespace llvm; 21 22 namespace { 23 24 /// A helper class that counts the total number of constructor and 25 /// destructor calls. 26 class Constructable { 27 private: 28 static int numConstructorCalls; 29 static int numMoveConstructorCalls; 30 static int numCopyConstructorCalls; 31 static int numDestructorCalls; 32 static int numAssignmentCalls; 33 static int numMoveAssignmentCalls; 34 static int numCopyAssignmentCalls; 35 36 bool constructed; 37 int value; 38 39 public: 40 Constructable() : constructed(true), value(0) { 41 ++numConstructorCalls; 42 } 43 44 Constructable(int val) : constructed(true), value(val) { 45 ++numConstructorCalls; 46 } 47 48 Constructable(const Constructable & src) : constructed(true) { 49 value = src.value; 50 ++numConstructorCalls; 51 ++numCopyConstructorCalls; 52 } 53 54 Constructable(Constructable && src) : constructed(true) { 55 value = src.value; 56 ++numConstructorCalls; 57 ++numMoveConstructorCalls; 58 } 59 60 ~Constructable() { 61 EXPECT_TRUE(constructed); 62 ++numDestructorCalls; 63 constructed = false; 64 } 65 66 Constructable & operator=(const Constructable & src) { 67 EXPECT_TRUE(constructed); 68 value = src.value; 69 ++numAssignmentCalls; 70 ++numCopyAssignmentCalls; 71 return *this; 72 } 73 74 Constructable & operator=(Constructable && src) { 75 EXPECT_TRUE(constructed); 76 value = src.value; 77 ++numAssignmentCalls; 78 ++numMoveAssignmentCalls; 79 return *this; 80 } 81 82 int getValue() const { 83 return abs(value); 84 } 85 86 static void reset() { 87 numConstructorCalls = 0; 88 numMoveConstructorCalls = 0; 89 numCopyConstructorCalls = 0; 90 numDestructorCalls = 0; 91 numAssignmentCalls = 0; 92 numMoveAssignmentCalls = 0; 93 numCopyAssignmentCalls = 0; 94 } 95 96 static int getNumConstructorCalls() { 97 return numConstructorCalls; 98 } 99 100 static int getNumMoveConstructorCalls() { 101 return numMoveConstructorCalls; 102 } 103 104 static int getNumCopyConstructorCalls() { 105 return numCopyConstructorCalls; 106 } 107 108 static int getNumDestructorCalls() { 109 return numDestructorCalls; 110 } 111 112 static int getNumAssignmentCalls() { 113 return numAssignmentCalls; 114 } 115 116 static int getNumMoveAssignmentCalls() { 117 return numMoveAssignmentCalls; 118 } 119 120 static int getNumCopyAssignmentCalls() { 121 return numCopyAssignmentCalls; 122 } 123 124 friend bool operator==(const Constructable & c0, const Constructable & c1) { 125 return c0.getValue() == c1.getValue(); 126 } 127 128 friend bool LLVM_ATTRIBUTE_UNUSED 129 operator!=(const Constructable & c0, const Constructable & c1) { 130 return c0.getValue() != c1.getValue(); 131 } 132 }; 133 134 int Constructable::numConstructorCalls; 135 int Constructable::numCopyConstructorCalls; 136 int Constructable::numMoveConstructorCalls; 137 int Constructable::numDestructorCalls; 138 int Constructable::numAssignmentCalls; 139 int Constructable::numCopyAssignmentCalls; 140 int Constructable::numMoveAssignmentCalls; 141 142 struct NonCopyable { 143 NonCopyable() {} 144 NonCopyable(NonCopyable &&) {} 145 NonCopyable &operator=(NonCopyable &&) { return *this; } 146 private: 147 NonCopyable(const NonCopyable &) = delete; 148 NonCopyable &operator=(const NonCopyable &) = delete; 149 }; 150 151 LLVM_ATTRIBUTE_USED void CompileTest() { 152 SmallVector<NonCopyable, 0> V; 153 V.resize(42); 154 } 155 156 class SmallVectorTestBase : public testing::Test { 157 protected: 158 void SetUp() override { Constructable::reset(); } 159 160 template <typename VectorT> 161 void assertEmpty(VectorT & v) { 162 // Size tests 163 EXPECT_EQ(0u, v.size()); 164 EXPECT_TRUE(v.empty()); 165 166 // Iterator tests 167 EXPECT_TRUE(v.begin() == v.end()); 168 } 169 170 // Assert that v contains the specified values, in order. 171 template <typename VectorT> 172 void assertValuesInOrder(VectorT & v, size_t size, ...) { 173 EXPECT_EQ(size, v.size()); 174 175 va_list ap; 176 va_start(ap, size); 177 for (size_t i = 0; i < size; ++i) { 178 int value = va_arg(ap, int); 179 EXPECT_EQ(value, v[i].getValue()); 180 } 181 182 va_end(ap); 183 } 184 185 // Generate a sequence of values to initialize the vector. 186 template <typename VectorT> 187 void makeSequence(VectorT & v, int start, int end) { 188 for (int i = start; i <= end; ++i) { 189 v.push_back(Constructable(i)); 190 } 191 } 192 }; 193 194 // Test fixture class 195 template <typename VectorT> 196 class SmallVectorTest : public SmallVectorTestBase { 197 protected: 198 VectorT theVector; 199 VectorT otherVector; 200 }; 201 202 203 typedef ::testing::Types<SmallVector<Constructable, 0>, 204 SmallVector<Constructable, 1>, 205 SmallVector<Constructable, 2>, 206 SmallVector<Constructable, 4>, 207 SmallVector<Constructable, 5> 208 > SmallVectorTestTypes; 209 TYPED_TEST_CASE(SmallVectorTest, SmallVectorTestTypes); 210 211 // Constructor test. 212 TYPED_TEST(SmallVectorTest, ConstructorNonIterTest) { 213 SCOPED_TRACE("ConstructorTest"); 214 this->theVector = SmallVector<Constructable, 2>(2, 2); 215 this->assertValuesInOrder(this->theVector, 2u, 2, 2); 216 } 217 218 // Constructor test. 219 TYPED_TEST(SmallVectorTest, ConstructorIterTest) { 220 SCOPED_TRACE("ConstructorTest"); 221 int arr[] = {1, 2, 3}; 222 this->theVector = 223 SmallVector<Constructable, 4>(std::begin(arr), std::end(arr)); 224 this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); 225 } 226 227 // New vector test. 228 TYPED_TEST(SmallVectorTest, EmptyVectorTest) { 229 SCOPED_TRACE("EmptyVectorTest"); 230 this->assertEmpty(this->theVector); 231 EXPECT_TRUE(this->theVector.rbegin() == this->theVector.rend()); 232 EXPECT_EQ(0, Constructable::getNumConstructorCalls()); 233 EXPECT_EQ(0, Constructable::getNumDestructorCalls()); 234 } 235 236 // Simple insertions and deletions. 237 TYPED_TEST(SmallVectorTest, PushPopTest) { 238 SCOPED_TRACE("PushPopTest"); 239 240 // Track whether the vector will potentially have to grow. 241 bool RequiresGrowth = this->theVector.capacity() < 3; 242 243 // Push an element 244 this->theVector.push_back(Constructable(1)); 245 246 // Size tests 247 this->assertValuesInOrder(this->theVector, 1u, 1); 248 EXPECT_FALSE(this->theVector.begin() == this->theVector.end()); 249 EXPECT_FALSE(this->theVector.empty()); 250 251 // Push another element 252 this->theVector.push_back(Constructable(2)); 253 this->assertValuesInOrder(this->theVector, 2u, 1, 2); 254 255 // Insert at beginning. Reserve space to avoid reference invalidation from 256 // this->theVector[1]. 257 this->theVector.reserve(this->theVector.size() + 1); 258 this->theVector.insert(this->theVector.begin(), this->theVector[1]); 259 this->assertValuesInOrder(this->theVector, 3u, 2, 1, 2); 260 261 // Pop one element 262 this->theVector.pop_back(); 263 this->assertValuesInOrder(this->theVector, 2u, 2, 1); 264 265 // Pop remaining elements 266 this->theVector.pop_back_n(2); 267 this->assertEmpty(this->theVector); 268 269 // Check number of constructor calls. Should be 2 for each list element, 270 // one for the argument to push_back, one for the argument to insert, 271 // and one for the list element itself. 272 if (!RequiresGrowth) { 273 EXPECT_EQ(5, Constructable::getNumConstructorCalls()); 274 EXPECT_EQ(5, Constructable::getNumDestructorCalls()); 275 } else { 276 // If we had to grow the vector, these only have a lower bound, but should 277 // always be equal. 278 EXPECT_LE(5, Constructable::getNumConstructorCalls()); 279 EXPECT_EQ(Constructable::getNumConstructorCalls(), 280 Constructable::getNumDestructorCalls()); 281 } 282 } 283 284 // Clear test. 285 TYPED_TEST(SmallVectorTest, ClearTest) { 286 SCOPED_TRACE("ClearTest"); 287 288 this->theVector.reserve(2); 289 this->makeSequence(this->theVector, 1, 2); 290 this->theVector.clear(); 291 292 this->assertEmpty(this->theVector); 293 EXPECT_EQ(4, Constructable::getNumConstructorCalls()); 294 EXPECT_EQ(4, Constructable::getNumDestructorCalls()); 295 } 296 297 // Resize smaller test. 298 TYPED_TEST(SmallVectorTest, ResizeShrinkTest) { 299 SCOPED_TRACE("ResizeShrinkTest"); 300 301 this->theVector.reserve(3); 302 this->makeSequence(this->theVector, 1, 3); 303 this->theVector.resize(1); 304 305 this->assertValuesInOrder(this->theVector, 1u, 1); 306 EXPECT_EQ(6, Constructable::getNumConstructorCalls()); 307 EXPECT_EQ(5, Constructable::getNumDestructorCalls()); 308 } 309 310 // Resize bigger test. 311 TYPED_TEST(SmallVectorTest, ResizeGrowTest) { 312 SCOPED_TRACE("ResizeGrowTest"); 313 314 this->theVector.resize(2); 315 316 EXPECT_EQ(2, Constructable::getNumConstructorCalls()); 317 EXPECT_EQ(0, Constructable::getNumDestructorCalls()); 318 EXPECT_EQ(2u, this->theVector.size()); 319 } 320 321 TYPED_TEST(SmallVectorTest, ResizeWithElementsTest) { 322 this->theVector.resize(2); 323 324 Constructable::reset(); 325 326 this->theVector.resize(4); 327 328 size_t Ctors = Constructable::getNumConstructorCalls(); 329 EXPECT_TRUE(Ctors == 2 || Ctors == 4); 330 size_t MoveCtors = Constructable::getNumMoveConstructorCalls(); 331 EXPECT_TRUE(MoveCtors == 0 || MoveCtors == 2); 332 size_t Dtors = Constructable::getNumDestructorCalls(); 333 EXPECT_TRUE(Dtors == 0 || Dtors == 2); 334 } 335 336 // Resize with fill value. 337 TYPED_TEST(SmallVectorTest, ResizeFillTest) { 338 SCOPED_TRACE("ResizeFillTest"); 339 340 this->theVector.resize(3, Constructable(77)); 341 this->assertValuesInOrder(this->theVector, 3u, 77, 77, 77); 342 } 343 344 // Overflow past fixed size. 345 TYPED_TEST(SmallVectorTest, OverflowTest) { 346 SCOPED_TRACE("OverflowTest"); 347 348 // Push more elements than the fixed size. 349 this->makeSequence(this->theVector, 1, 10); 350 351 // Test size and values. 352 EXPECT_EQ(10u, this->theVector.size()); 353 for (int i = 0; i < 10; ++i) { 354 EXPECT_EQ(i+1, this->theVector[i].getValue()); 355 } 356 357 // Now resize back to fixed size. 358 this->theVector.resize(1); 359 360 this->assertValuesInOrder(this->theVector, 1u, 1); 361 } 362 363 // Iteration tests. 364 TYPED_TEST(SmallVectorTest, IterationTest) { 365 this->makeSequence(this->theVector, 1, 2); 366 367 // Forward Iteration 368 typename TypeParam::iterator it = this->theVector.begin(); 369 EXPECT_TRUE(*it == this->theVector.front()); 370 EXPECT_TRUE(*it == this->theVector[0]); 371 EXPECT_EQ(1, it->getValue()); 372 ++it; 373 EXPECT_TRUE(*it == this->theVector[1]); 374 EXPECT_TRUE(*it == this->theVector.back()); 375 EXPECT_EQ(2, it->getValue()); 376 ++it; 377 EXPECT_TRUE(it == this->theVector.end()); 378 --it; 379 EXPECT_TRUE(*it == this->theVector[1]); 380 EXPECT_EQ(2, it->getValue()); 381 --it; 382 EXPECT_TRUE(*it == this->theVector[0]); 383 EXPECT_EQ(1, it->getValue()); 384 385 // Reverse Iteration 386 typename TypeParam::reverse_iterator rit = this->theVector.rbegin(); 387 EXPECT_TRUE(*rit == this->theVector[1]); 388 EXPECT_EQ(2, rit->getValue()); 389 ++rit; 390 EXPECT_TRUE(*rit == this->theVector[0]); 391 EXPECT_EQ(1, rit->getValue()); 392 ++rit; 393 EXPECT_TRUE(rit == this->theVector.rend()); 394 --rit; 395 EXPECT_TRUE(*rit == this->theVector[0]); 396 EXPECT_EQ(1, rit->getValue()); 397 --rit; 398 EXPECT_TRUE(*rit == this->theVector[1]); 399 EXPECT_EQ(2, rit->getValue()); 400 } 401 402 // Swap test. 403 TYPED_TEST(SmallVectorTest, SwapTest) { 404 SCOPED_TRACE("SwapTest"); 405 406 this->makeSequence(this->theVector, 1, 2); 407 std::swap(this->theVector, this->otherVector); 408 409 this->assertEmpty(this->theVector); 410 this->assertValuesInOrder(this->otherVector, 2u, 1, 2); 411 } 412 413 // Append test 414 TYPED_TEST(SmallVectorTest, AppendTest) { 415 SCOPED_TRACE("AppendTest"); 416 417 this->makeSequence(this->otherVector, 2, 3); 418 419 this->theVector.push_back(Constructable(1)); 420 this->theVector.append(this->otherVector.begin(), this->otherVector.end()); 421 422 this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); 423 } 424 425 // Append repeated test 426 TYPED_TEST(SmallVectorTest, AppendRepeatedTest) { 427 SCOPED_TRACE("AppendRepeatedTest"); 428 429 this->theVector.push_back(Constructable(1)); 430 this->theVector.append(2, Constructable(77)); 431 this->assertValuesInOrder(this->theVector, 3u, 1, 77, 77); 432 } 433 434 // Append test 435 TYPED_TEST(SmallVectorTest, AppendNonIterTest) { 436 SCOPED_TRACE("AppendRepeatedTest"); 437 438 this->theVector.push_back(Constructable(1)); 439 this->theVector.append(2, 7); 440 this->assertValuesInOrder(this->theVector, 3u, 1, 7, 7); 441 } 442 443 struct output_iterator { 444 typedef std::output_iterator_tag iterator_category; 445 typedef int value_type; 446 typedef int difference_type; 447 typedef value_type *pointer; 448 typedef value_type &reference; 449 operator int() { return 2; } 450 operator Constructable() { return 7; } 451 }; 452 453 TYPED_TEST(SmallVectorTest, AppendRepeatedNonForwardIterator) { 454 SCOPED_TRACE("AppendRepeatedTest"); 455 456 this->theVector.push_back(Constructable(1)); 457 this->theVector.append(output_iterator(), output_iterator()); 458 this->assertValuesInOrder(this->theVector, 3u, 1, 7, 7); 459 } 460 461 // Assign test 462 TYPED_TEST(SmallVectorTest, AssignTest) { 463 SCOPED_TRACE("AssignTest"); 464 465 this->theVector.push_back(Constructable(1)); 466 this->theVector.assign(2, Constructable(77)); 467 this->assertValuesInOrder(this->theVector, 2u, 77, 77); 468 } 469 470 // Assign test 471 TYPED_TEST(SmallVectorTest, AssignRangeTest) { 472 SCOPED_TRACE("AssignTest"); 473 474 this->theVector.push_back(Constructable(1)); 475 int arr[] = {1, 2, 3}; 476 this->theVector.assign(std::begin(arr), std::end(arr)); 477 this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); 478 } 479 480 // Assign test 481 TYPED_TEST(SmallVectorTest, AssignNonIterTest) { 482 SCOPED_TRACE("AssignTest"); 483 484 this->theVector.push_back(Constructable(1)); 485 this->theVector.assign(2, 7); 486 this->assertValuesInOrder(this->theVector, 2u, 7, 7); 487 } 488 489 // Move-assign test 490 TYPED_TEST(SmallVectorTest, MoveAssignTest) { 491 SCOPED_TRACE("MoveAssignTest"); 492 493 // Set up our vector with a single element, but enough capacity for 4. 494 this->theVector.reserve(4); 495 this->theVector.push_back(Constructable(1)); 496 497 // Set up the other vector with 2 elements. 498 this->otherVector.push_back(Constructable(2)); 499 this->otherVector.push_back(Constructable(3)); 500 501 // Move-assign from the other vector. 502 this->theVector = std::move(this->otherVector); 503 504 // Make sure we have the right result. 505 this->assertValuesInOrder(this->theVector, 2u, 2, 3); 506 507 // Make sure the # of constructor/destructor calls line up. There 508 // are two live objects after clearing the other vector. 509 this->otherVector.clear(); 510 EXPECT_EQ(Constructable::getNumConstructorCalls()-2, 511 Constructable::getNumDestructorCalls()); 512 513 // There shouldn't be any live objects any more. 514 this->theVector.clear(); 515 EXPECT_EQ(Constructable::getNumConstructorCalls(), 516 Constructable::getNumDestructorCalls()); 517 } 518 519 // Erase a single element 520 TYPED_TEST(SmallVectorTest, EraseTest) { 521 SCOPED_TRACE("EraseTest"); 522 523 this->makeSequence(this->theVector, 1, 3); 524 const auto &theConstVector = this->theVector; 525 this->theVector.erase(theConstVector.begin()); 526 this->assertValuesInOrder(this->theVector, 2u, 2, 3); 527 } 528 529 // Erase a range of elements 530 TYPED_TEST(SmallVectorTest, EraseRangeTest) { 531 SCOPED_TRACE("EraseRangeTest"); 532 533 this->makeSequence(this->theVector, 1, 3); 534 const auto &theConstVector = this->theVector; 535 this->theVector.erase(theConstVector.begin(), theConstVector.begin() + 2); 536 this->assertValuesInOrder(this->theVector, 1u, 3); 537 } 538 539 // Insert a single element. 540 TYPED_TEST(SmallVectorTest, InsertTest) { 541 SCOPED_TRACE("InsertTest"); 542 543 this->makeSequence(this->theVector, 1, 3); 544 typename TypeParam::iterator I = 545 this->theVector.insert(this->theVector.begin() + 1, Constructable(77)); 546 EXPECT_EQ(this->theVector.begin() + 1, I); 547 this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3); 548 } 549 550 // Insert a copy of a single element. 551 TYPED_TEST(SmallVectorTest, InsertCopy) { 552 SCOPED_TRACE("InsertTest"); 553 554 this->makeSequence(this->theVector, 1, 3); 555 Constructable C(77); 556 typename TypeParam::iterator I = 557 this->theVector.insert(this->theVector.begin() + 1, C); 558 EXPECT_EQ(this->theVector.begin() + 1, I); 559 this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3); 560 } 561 562 // Insert repeated elements. 563 TYPED_TEST(SmallVectorTest, InsertRepeatedTest) { 564 SCOPED_TRACE("InsertRepeatedTest"); 565 566 this->makeSequence(this->theVector, 1, 4); 567 Constructable::reset(); 568 auto I = 569 this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16)); 570 // Move construct the top element into newly allocated space, and optionally 571 // reallocate the whole buffer, move constructing into it. 572 // FIXME: This is inefficient, we shouldn't move things into newly allocated 573 // space, then move them up/around, there should only be 2 or 4 move 574 // constructions here. 575 EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 2 || 576 Constructable::getNumMoveConstructorCalls() == 6); 577 // Move assign the next two to shift them up and make a gap. 578 EXPECT_EQ(1, Constructable::getNumMoveAssignmentCalls()); 579 // Copy construct the two new elements from the parameter. 580 EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls()); 581 // All without any copy construction. 582 EXPECT_EQ(0, Constructable::getNumCopyConstructorCalls()); 583 EXPECT_EQ(this->theVector.begin() + 1, I); 584 this->assertValuesInOrder(this->theVector, 6u, 1, 16, 16, 2, 3, 4); 585 } 586 587 TYPED_TEST(SmallVectorTest, InsertRepeatedNonIterTest) { 588 SCOPED_TRACE("InsertRepeatedTest"); 589 590 this->makeSequence(this->theVector, 1, 4); 591 Constructable::reset(); 592 auto I = this->theVector.insert(this->theVector.begin() + 1, 2, 7); 593 EXPECT_EQ(this->theVector.begin() + 1, I); 594 this->assertValuesInOrder(this->theVector, 6u, 1, 7, 7, 2, 3, 4); 595 } 596 597 TYPED_TEST(SmallVectorTest, InsertRepeatedAtEndTest) { 598 SCOPED_TRACE("InsertRepeatedTest"); 599 600 this->makeSequence(this->theVector, 1, 4); 601 Constructable::reset(); 602 auto I = this->theVector.insert(this->theVector.end(), 2, Constructable(16)); 603 // Just copy construct them into newly allocated space 604 EXPECT_EQ(2, Constructable::getNumCopyConstructorCalls()); 605 // Move everything across if reallocation is needed. 606 EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 || 607 Constructable::getNumMoveConstructorCalls() == 4); 608 // Without ever moving or copying anything else. 609 EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls()); 610 EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls()); 611 612 EXPECT_EQ(this->theVector.begin() + 4, I); 613 this->assertValuesInOrder(this->theVector, 6u, 1, 2, 3, 4, 16, 16); 614 } 615 616 TYPED_TEST(SmallVectorTest, InsertRepeatedEmptyTest) { 617 SCOPED_TRACE("InsertRepeatedTest"); 618 619 this->makeSequence(this->theVector, 10, 15); 620 621 // Empty insert. 622 EXPECT_EQ(this->theVector.end(), 623 this->theVector.insert(this->theVector.end(), 624 0, Constructable(42))); 625 EXPECT_EQ(this->theVector.begin() + 1, 626 this->theVector.insert(this->theVector.begin() + 1, 627 0, Constructable(42))); 628 } 629 630 // Insert range. 631 TYPED_TEST(SmallVectorTest, InsertRangeTest) { 632 SCOPED_TRACE("InsertRangeTest"); 633 634 Constructable Arr[3] = 635 { Constructable(77), Constructable(77), Constructable(77) }; 636 637 this->makeSequence(this->theVector, 1, 3); 638 Constructable::reset(); 639 auto I = this->theVector.insert(this->theVector.begin() + 1, Arr, Arr + 3); 640 // Move construct the top 3 elements into newly allocated space. 641 // Possibly move the whole sequence into new space first. 642 // FIXME: This is inefficient, we shouldn't move things into newly allocated 643 // space, then move them up/around, there should only be 2 or 3 move 644 // constructions here. 645 EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 2 || 646 Constructable::getNumMoveConstructorCalls() == 5); 647 // Copy assign the lower 2 new elements into existing space. 648 EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls()); 649 // Copy construct the third element into newly allocated space. 650 EXPECT_EQ(1, Constructable::getNumCopyConstructorCalls()); 651 EXPECT_EQ(this->theVector.begin() + 1, I); 652 this->assertValuesInOrder(this->theVector, 6u, 1, 77, 77, 77, 2, 3); 653 } 654 655 656 TYPED_TEST(SmallVectorTest, InsertRangeAtEndTest) { 657 SCOPED_TRACE("InsertRangeTest"); 658 659 Constructable Arr[3] = 660 { Constructable(77), Constructable(77), Constructable(77) }; 661 662 this->makeSequence(this->theVector, 1, 3); 663 664 // Insert at end. 665 Constructable::reset(); 666 auto I = this->theVector.insert(this->theVector.end(), Arr, Arr+3); 667 // Copy construct the 3 elements into new space at the top. 668 EXPECT_EQ(3, Constructable::getNumCopyConstructorCalls()); 669 // Don't copy/move anything else. 670 EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls()); 671 // Reallocation might occur, causing all elements to be moved into the new 672 // buffer. 673 EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 || 674 Constructable::getNumMoveConstructorCalls() == 3); 675 EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls()); 676 EXPECT_EQ(this->theVector.begin() + 3, I); 677 this->assertValuesInOrder(this->theVector, 6u, 678 1, 2, 3, 77, 77, 77); 679 } 680 681 TYPED_TEST(SmallVectorTest, InsertEmptyRangeTest) { 682 SCOPED_TRACE("InsertRangeTest"); 683 684 this->makeSequence(this->theVector, 1, 3); 685 686 // Empty insert. 687 EXPECT_EQ(this->theVector.end(), 688 this->theVector.insert(this->theVector.end(), 689 this->theVector.begin(), 690 this->theVector.begin())); 691 EXPECT_EQ(this->theVector.begin() + 1, 692 this->theVector.insert(this->theVector.begin() + 1, 693 this->theVector.begin(), 694 this->theVector.begin())); 695 } 696 697 // Comparison tests. 698 TYPED_TEST(SmallVectorTest, ComparisonTest) { 699 SCOPED_TRACE("ComparisonTest"); 700 701 this->makeSequence(this->theVector, 1, 3); 702 this->makeSequence(this->otherVector, 1, 3); 703 704 EXPECT_TRUE(this->theVector == this->otherVector); 705 EXPECT_FALSE(this->theVector != this->otherVector); 706 707 this->otherVector.clear(); 708 this->makeSequence(this->otherVector, 2, 4); 709 710 EXPECT_FALSE(this->theVector == this->otherVector); 711 EXPECT_TRUE(this->theVector != this->otherVector); 712 } 713 714 // Constant vector tests. 715 TYPED_TEST(SmallVectorTest, ConstVectorTest) { 716 const TypeParam constVector; 717 718 EXPECT_EQ(0u, constVector.size()); 719 EXPECT_TRUE(constVector.empty()); 720 EXPECT_TRUE(constVector.begin() == constVector.end()); 721 } 722 723 // Direct array access. 724 TYPED_TEST(SmallVectorTest, DirectVectorTest) { 725 EXPECT_EQ(0u, this->theVector.size()); 726 this->theVector.reserve(4); 727 EXPECT_LE(4u, this->theVector.capacity()); 728 EXPECT_EQ(0, Constructable::getNumConstructorCalls()); 729 this->theVector.push_back(1); 730 this->theVector.push_back(2); 731 this->theVector.push_back(3); 732 this->theVector.push_back(4); 733 EXPECT_EQ(4u, this->theVector.size()); 734 EXPECT_EQ(8, Constructable::getNumConstructorCalls()); 735 EXPECT_EQ(1, this->theVector[0].getValue()); 736 EXPECT_EQ(2, this->theVector[1].getValue()); 737 EXPECT_EQ(3, this->theVector[2].getValue()); 738 EXPECT_EQ(4, this->theVector[3].getValue()); 739 } 740 741 TYPED_TEST(SmallVectorTest, IteratorTest) { 742 std::list<int> L; 743 this->theVector.insert(this->theVector.end(), L.begin(), L.end()); 744 } 745 746 template <typename InvalidType> class DualSmallVectorsTest; 747 748 template <typename VectorT1, typename VectorT2> 749 class DualSmallVectorsTest<std::pair<VectorT1, VectorT2>> : public SmallVectorTestBase { 750 protected: 751 VectorT1 theVector; 752 VectorT2 otherVector; 753 754 template <typename T, unsigned N> 755 static unsigned NumBuiltinElts(const SmallVector<T, N>&) { return N; } 756 }; 757 758 typedef ::testing::Types< 759 // Small mode -> Small mode. 760 std::pair<SmallVector<Constructable, 4>, SmallVector<Constructable, 4>>, 761 // Small mode -> Big mode. 762 std::pair<SmallVector<Constructable, 4>, SmallVector<Constructable, 2>>, 763 // Big mode -> Small mode. 764 std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 4>>, 765 // Big mode -> Big mode. 766 std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 2>> 767 > DualSmallVectorTestTypes; 768 769 TYPED_TEST_CASE(DualSmallVectorsTest, DualSmallVectorTestTypes); 770 771 TYPED_TEST(DualSmallVectorsTest, MoveAssignment) { 772 SCOPED_TRACE("MoveAssignTest-DualVectorTypes"); 773 774 // Set up our vector with four elements. 775 for (unsigned I = 0; I < 4; ++I) 776 this->otherVector.push_back(Constructable(I)); 777 778 const Constructable *OrigDataPtr = this->otherVector.data(); 779 780 // Move-assign from the other vector. 781 this->theVector = 782 std::move(static_cast<SmallVectorImpl<Constructable>&>(this->otherVector)); 783 784 // Make sure we have the right result. 785 this->assertValuesInOrder(this->theVector, 4u, 0, 1, 2, 3); 786 787 // Make sure the # of constructor/destructor calls line up. There 788 // are two live objects after clearing the other vector. 789 this->otherVector.clear(); 790 EXPECT_EQ(Constructable::getNumConstructorCalls()-4, 791 Constructable::getNumDestructorCalls()); 792 793 // If the source vector (otherVector) was in small-mode, assert that we just 794 // moved the data pointer over. 795 EXPECT_TRUE(this->NumBuiltinElts(this->otherVector) == 4 || 796 this->theVector.data() == OrigDataPtr); 797 798 // There shouldn't be any live objects any more. 799 this->theVector.clear(); 800 EXPECT_EQ(Constructable::getNumConstructorCalls(), 801 Constructable::getNumDestructorCalls()); 802 803 // We shouldn't have copied anything in this whole process. 804 EXPECT_EQ(Constructable::getNumCopyConstructorCalls(), 0); 805 } 806 807 struct notassignable { 808 int &x; 809 notassignable(int &x) : x(x) {} 810 }; 811 812 TEST(SmallVectorCustomTest, NoAssignTest) { 813 int x = 0; 814 SmallVector<notassignable, 2> vec; 815 vec.push_back(notassignable(x)); 816 x = 42; 817 EXPECT_EQ(42, vec.pop_back_val().x); 818 } 819 820 struct MovedFrom { 821 bool hasValue; 822 MovedFrom() : hasValue(true) { 823 } 824 MovedFrom(MovedFrom&& m) : hasValue(m.hasValue) { 825 m.hasValue = false; 826 } 827 MovedFrom &operator=(MovedFrom&& m) { 828 hasValue = m.hasValue; 829 m.hasValue = false; 830 return *this; 831 } 832 }; 833 834 TEST(SmallVectorTest, MidInsert) { 835 SmallVector<MovedFrom, 3> v; 836 v.push_back(MovedFrom()); 837 v.insert(v.begin(), MovedFrom()); 838 for (MovedFrom &m : v) 839 EXPECT_TRUE(m.hasValue); 840 } 841 842 enum EmplaceableArgState { 843 EAS_Defaulted, 844 EAS_Arg, 845 EAS_LValue, 846 EAS_RValue, 847 EAS_Failure 848 }; 849 template <int I> struct EmplaceableArg { 850 EmplaceableArgState State; 851 EmplaceableArg() : State(EAS_Defaulted) {} 852 EmplaceableArg(EmplaceableArg &&X) 853 : State(X.State == EAS_Arg ? EAS_RValue : EAS_Failure) {} 854 EmplaceableArg(EmplaceableArg &X) 855 : State(X.State == EAS_Arg ? EAS_LValue : EAS_Failure) {} 856 857 explicit EmplaceableArg(bool) : State(EAS_Arg) {} 858 859 private: 860 EmplaceableArg &operator=(EmplaceableArg &&) = delete; 861 EmplaceableArg &operator=(const EmplaceableArg &) = delete; 862 }; 863 864 enum EmplaceableState { ES_Emplaced, ES_Moved }; 865 struct Emplaceable { 866 EmplaceableArg<0> A0; 867 EmplaceableArg<1> A1; 868 EmplaceableArg<2> A2; 869 EmplaceableArg<3> A3; 870 EmplaceableState State; 871 872 Emplaceable() : State(ES_Emplaced) {} 873 874 template <class A0Ty> 875 explicit Emplaceable(A0Ty &&A0) 876 : A0(std::forward<A0Ty>(A0)), State(ES_Emplaced) {} 877 878 template <class A0Ty, class A1Ty> 879 Emplaceable(A0Ty &&A0, A1Ty &&A1) 880 : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)), 881 State(ES_Emplaced) {} 882 883 template <class A0Ty, class A1Ty, class A2Ty> 884 Emplaceable(A0Ty &&A0, A1Ty &&A1, A2Ty &&A2) 885 : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)), 886 A2(std::forward<A2Ty>(A2)), State(ES_Emplaced) {} 887 888 template <class A0Ty, class A1Ty, class A2Ty, class A3Ty> 889 Emplaceable(A0Ty &&A0, A1Ty &&A1, A2Ty &&A2, A3Ty &&A3) 890 : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)), 891 A2(std::forward<A2Ty>(A2)), A3(std::forward<A3Ty>(A3)), 892 State(ES_Emplaced) {} 893 894 Emplaceable(Emplaceable &&) : State(ES_Moved) {} 895 Emplaceable &operator=(Emplaceable &&) { 896 State = ES_Moved; 897 return *this; 898 } 899 900 private: 901 Emplaceable(const Emplaceable &) = delete; 902 Emplaceable &operator=(const Emplaceable &) = delete; 903 }; 904 905 TEST(SmallVectorTest, EmplaceBack) { 906 EmplaceableArg<0> A0(true); 907 EmplaceableArg<1> A1(true); 908 EmplaceableArg<2> A2(true); 909 EmplaceableArg<3> A3(true); 910 { 911 SmallVector<Emplaceable, 3> V; 912 Emplaceable &back = V.emplace_back(); 913 EXPECT_TRUE(&back == &V.back()); 914 EXPECT_TRUE(V.size() == 1); 915 EXPECT_TRUE(back.State == ES_Emplaced); 916 EXPECT_TRUE(back.A0.State == EAS_Defaulted); 917 EXPECT_TRUE(back.A1.State == EAS_Defaulted); 918 EXPECT_TRUE(back.A2.State == EAS_Defaulted); 919 EXPECT_TRUE(back.A3.State == EAS_Defaulted); 920 } 921 { 922 SmallVector<Emplaceable, 3> V; 923 Emplaceable &back = V.emplace_back(std::move(A0)); 924 EXPECT_TRUE(&back == &V.back()); 925 EXPECT_TRUE(V.size() == 1); 926 EXPECT_TRUE(back.State == ES_Emplaced); 927 EXPECT_TRUE(back.A0.State == EAS_RValue); 928 EXPECT_TRUE(back.A1.State == EAS_Defaulted); 929 EXPECT_TRUE(back.A2.State == EAS_Defaulted); 930 EXPECT_TRUE(back.A3.State == EAS_Defaulted); 931 } 932 { 933 SmallVector<Emplaceable, 3> V; 934 Emplaceable &back = V.emplace_back(A0); 935 EXPECT_TRUE(&back == &V.back()); 936 EXPECT_TRUE(V.size() == 1); 937 EXPECT_TRUE(back.State == ES_Emplaced); 938 EXPECT_TRUE(back.A0.State == EAS_LValue); 939 EXPECT_TRUE(back.A1.State == EAS_Defaulted); 940 EXPECT_TRUE(back.A2.State == EAS_Defaulted); 941 EXPECT_TRUE(back.A3.State == EAS_Defaulted); 942 } 943 { 944 SmallVector<Emplaceable, 3> V; 945 Emplaceable &back = V.emplace_back(A0, A1); 946 EXPECT_TRUE(&back == &V.back()); 947 EXPECT_TRUE(V.size() == 1); 948 EXPECT_TRUE(back.State == ES_Emplaced); 949 EXPECT_TRUE(back.A0.State == EAS_LValue); 950 EXPECT_TRUE(back.A1.State == EAS_LValue); 951 EXPECT_TRUE(back.A2.State == EAS_Defaulted); 952 EXPECT_TRUE(back.A3.State == EAS_Defaulted); 953 } 954 { 955 SmallVector<Emplaceable, 3> V; 956 Emplaceable &back = V.emplace_back(std::move(A0), std::move(A1)); 957 EXPECT_TRUE(&back == &V.back()); 958 EXPECT_TRUE(V.size() == 1); 959 EXPECT_TRUE(back.State == ES_Emplaced); 960 EXPECT_TRUE(back.A0.State == EAS_RValue); 961 EXPECT_TRUE(back.A1.State == EAS_RValue); 962 EXPECT_TRUE(back.A2.State == EAS_Defaulted); 963 EXPECT_TRUE(back.A3.State == EAS_Defaulted); 964 } 965 { 966 SmallVector<Emplaceable, 3> V; 967 Emplaceable &back = V.emplace_back(std::move(A0), A1, std::move(A2), A3); 968 EXPECT_TRUE(&back == &V.back()); 969 EXPECT_TRUE(V.size() == 1); 970 EXPECT_TRUE(back.State == ES_Emplaced); 971 EXPECT_TRUE(back.A0.State == EAS_RValue); 972 EXPECT_TRUE(back.A1.State == EAS_LValue); 973 EXPECT_TRUE(back.A2.State == EAS_RValue); 974 EXPECT_TRUE(back.A3.State == EAS_LValue); 975 } 976 { 977 SmallVector<int, 1> V; 978 V.emplace_back(); 979 V.emplace_back(42); 980 EXPECT_EQ(2U, V.size()); 981 EXPECT_EQ(0, V[0]); 982 EXPECT_EQ(42, V[1]); 983 } 984 } 985 986 TEST(SmallVectorTest, InitializerList) { 987 SmallVector<int, 2> V1 = {}; 988 EXPECT_TRUE(V1.empty()); 989 V1 = {0, 0}; 990 EXPECT_TRUE(makeArrayRef(V1).equals({0, 0})); 991 V1 = {-1, -1}; 992 EXPECT_TRUE(makeArrayRef(V1).equals({-1, -1})); 993 994 SmallVector<int, 2> V2 = {1, 2, 3, 4}; 995 EXPECT_TRUE(makeArrayRef(V2).equals({1, 2, 3, 4})); 996 V2.assign({4}); 997 EXPECT_TRUE(makeArrayRef(V2).equals({4})); 998 V2.append({3, 2}); 999 EXPECT_TRUE(makeArrayRef(V2).equals({4, 3, 2})); 1000 V2.insert(V2.begin() + 1, 5); 1001 EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2})); 1002 } 1003 1004 template <class VectorT> 1005 class SmallVectorReferenceInvalidationTest : public SmallVectorTestBase { 1006 protected: 1007 const char *AssertionMessage = 1008 "Attempting to reference an element of the vector in an operation \" " 1009 "\"that invalidates it"; 1010 1011 VectorT V; 1012 1013 template <typename T, unsigned N> 1014 static unsigned NumBuiltinElts(const SmallVector<T, N> &) { 1015 return N; 1016 } 1017 1018 void SetUp() override { 1019 SmallVectorTestBase::SetUp(); 1020 1021 // Fill up the small size so that insertions move the elements. 1022 V.append({0, 0, 0}); 1023 } 1024 }; 1025 1026 // Test one type that's trivially copyable (int) and one that isn't 1027 // (Constructable) since reference invalidation may be fixed differently for 1028 // each. 1029 using SmallVectorReferenceInvalidationTestTypes = 1030 ::testing::Types<SmallVector<int, 3>, SmallVector<Constructable, 3>>; 1031 1032 TYPED_TEST_CASE(SmallVectorReferenceInvalidationTest, 1033 SmallVectorReferenceInvalidationTestTypes); 1034 1035 TYPED_TEST(SmallVectorReferenceInvalidationTest, PushBack) { 1036 auto &V = this->V; 1037 (void)V; 1038 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1039 EXPECT_DEATH(V.push_back(V.back()), this->AssertionMessage); 1040 #endif 1041 } 1042 1043 TYPED_TEST(SmallVectorReferenceInvalidationTest, PushBackMoved) { 1044 auto &V = this->V; 1045 (void)V; 1046 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1047 EXPECT_DEATH(V.push_back(std::move(V.back())), this->AssertionMessage); 1048 #endif 1049 } 1050 1051 TYPED_TEST(SmallVectorReferenceInvalidationTest, Resize) { 1052 auto &V = this->V; 1053 (void)V; 1054 int N = this->NumBuiltinElts(V); 1055 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1056 EXPECT_DEATH(V.resize(N + 1, V.back()), this->AssertionMessage); 1057 #endif 1058 1059 // No assertion when shrinking, since the parameter isn't accessed. 1060 V.resize(N - 1, V.back()); 1061 } 1062 1063 TYPED_TEST(SmallVectorReferenceInvalidationTest, Append) { 1064 auto &V = this->V; 1065 (void)V; 1066 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1067 EXPECT_DEATH(V.append(1, V.back()), this->AssertionMessage); 1068 #endif 1069 } 1070 1071 TYPED_TEST(SmallVectorReferenceInvalidationTest, AppendRange) { 1072 auto &V = this->V; 1073 (void)V; 1074 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1075 EXPECT_DEATH(V.append(V.begin(), V.begin() + 1), this->AssertionMessage); 1076 1077 ASSERT_EQ(3u, this->NumBuiltinElts(V)); 1078 ASSERT_EQ(3u, V.size()); 1079 V.pop_back(); 1080 ASSERT_EQ(2u, V.size()); 1081 1082 // Confirm this checks for growth when there's more than one element 1083 // appended. 1084 EXPECT_DEATH(V.append(V.begin(), V.end()), this->AssertionMessage); 1085 #endif 1086 } 1087 1088 TYPED_TEST(SmallVectorReferenceInvalidationTest, Assign) { 1089 auto &V = this->V; 1090 (void)V; 1091 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1092 // Regardless of capacity, assign should never reference an internal element. 1093 EXPECT_DEATH(V.assign(1, V.back()), this->AssertionMessage); 1094 EXPECT_DEATH(V.assign(this->NumBuiltinElts(V), V.back()), 1095 this->AssertionMessage); 1096 EXPECT_DEATH(V.assign(this->NumBuiltinElts(V) + 1, V.back()), 1097 this->AssertionMessage); 1098 #endif 1099 } 1100 1101 TYPED_TEST(SmallVectorReferenceInvalidationTest, AssignRange) { 1102 auto &V = this->V; 1103 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1104 EXPECT_DEATH(V.assign(V.begin(), V.end()), this->AssertionMessage); 1105 EXPECT_DEATH(V.assign(V.begin(), V.end() - 1), this->AssertionMessage); 1106 #endif 1107 V.assign(V.begin(), V.begin()); 1108 EXPECT_TRUE(V.empty()); 1109 } 1110 1111 TYPED_TEST(SmallVectorReferenceInvalidationTest, Insert) { 1112 auto &V = this->V; 1113 (void)V; 1114 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1115 EXPECT_DEATH(V.insert(V.begin(), V.back()), this->AssertionMessage); 1116 #endif 1117 } 1118 1119 TYPED_TEST(SmallVectorReferenceInvalidationTest, InsertMoved) { 1120 auto &V = this->V; 1121 (void)V; 1122 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1123 EXPECT_DEATH(V.insert(V.begin(), std::move(V.back())), 1124 this->AssertionMessage); 1125 #endif 1126 } 1127 1128 TYPED_TEST(SmallVectorReferenceInvalidationTest, InsertN) { 1129 auto &V = this->V; 1130 (void)V; 1131 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1132 EXPECT_DEATH(V.insert(V.begin(), 2, V.back()), this->AssertionMessage); 1133 #endif 1134 } 1135 1136 TYPED_TEST(SmallVectorReferenceInvalidationTest, InsertRange) { 1137 auto &V = this->V; 1138 (void)V; 1139 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1140 EXPECT_DEATH(V.insert(V.begin(), V.begin(), V.begin() + 1), 1141 this->AssertionMessage); 1142 1143 ASSERT_EQ(3u, this->NumBuiltinElts(V)); 1144 ASSERT_EQ(3u, V.size()); 1145 V.pop_back(); 1146 ASSERT_EQ(2u, V.size()); 1147 1148 // Confirm this checks for growth when there's more than one element 1149 // inserted. 1150 EXPECT_DEATH(V.insert(V.begin(), V.begin(), V.end()), this->AssertionMessage); 1151 #endif 1152 } 1153 1154 TYPED_TEST(SmallVectorReferenceInvalidationTest, EmplaceBack) { 1155 auto &V = this->V; 1156 (void)V; 1157 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1158 EXPECT_DEATH(V.emplace_back(V.back()), this->AssertionMessage); 1159 #endif 1160 } 1161 1162 template <class VectorT> 1163 class SmallVectorInternalReferenceInvalidationTest 1164 : public SmallVectorTestBase { 1165 protected: 1166 const char *AssertionMessage = 1167 "Attempting to reference an element of the vector in an operation \" " 1168 "\"that invalidates it"; 1169 1170 VectorT V; 1171 1172 template <typename T, unsigned N> 1173 static unsigned NumBuiltinElts(const SmallVector<T, N> &) { 1174 return N; 1175 } 1176 1177 void SetUp() override { 1178 SmallVectorTestBase::SetUp(); 1179 1180 // Fill up the small size so that insertions move the elements. 1181 V.push_back(std::make_pair(0, 0)); 1182 } 1183 }; 1184 1185 // Test pairs of the same types from SmallVectorReferenceInvalidationTestTypes. 1186 using SmallVectorInternalReferenceInvalidationTestTypes = 1187 ::testing::Types<SmallVector<std::pair<int, int>, 1>, 1188 SmallVector<std::pair<Constructable, Constructable>, 1>>; 1189 1190 TYPED_TEST_CASE(SmallVectorInternalReferenceInvalidationTest, 1191 SmallVectorInternalReferenceInvalidationTestTypes); 1192 1193 TYPED_TEST(SmallVectorInternalReferenceInvalidationTest, EmplaceBack) { 1194 auto &V = this->V; 1195 (void)V; 1196 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 1197 EXPECT_DEATH(V.emplace_back(V.back().first, 0), this->AssertionMessage); 1198 EXPECT_DEATH(V.emplace_back(0, V.back().second), this->AssertionMessage); 1199 #endif 1200 } 1201 1202 } // end namespace 1203