00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/container/inlined_vector.h"
00016
00017 #include <algorithm>
00018 #include <forward_list>
00019 #include <list>
00020 #include <memory>
00021 #include <scoped_allocator>
00022 #include <sstream>
00023 #include <stdexcept>
00024 #include <string>
00025 #include <vector>
00026
00027 #include "gmock/gmock.h"
00028 #include "gtest/gtest.h"
00029 #include "absl/base/attributes.h"
00030 #include "absl/base/internal/exception_testing.h"
00031 #include "absl/base/internal/raw_logging.h"
00032 #include "absl/base/macros.h"
00033 #include "absl/container/internal/counting_allocator.h"
00034 #include "absl/container/internal/test_instance_tracker.h"
00035 #include "absl/hash/hash_testing.h"
00036 #include "absl/memory/memory.h"
00037 #include "absl/strings/str_cat.h"
00038
00039 namespace {
00040
00041 using absl::container_internal::CountingAllocator;
00042 using absl::test_internal::CopyableMovableInstance;
00043 using absl::test_internal::CopyableOnlyInstance;
00044 using absl::test_internal::InstanceTracker;
00045 using testing::AllOf;
00046 using testing::Each;
00047 using testing::ElementsAre;
00048 using testing::ElementsAreArray;
00049 using testing::Eq;
00050 using testing::Gt;
00051 using testing::PrintToString;
00052
00053 using IntVec = absl::InlinedVector<int, 8>;
00054
00055 MATCHER_P(SizeIs, n, "") {
00056 return testing::ExplainMatchResult(n, arg.size(), result_listener);
00057 }
00058
00059 MATCHER_P(CapacityIs, n, "") {
00060 return testing::ExplainMatchResult(n, arg.capacity(), result_listener);
00061 }
00062
00063 MATCHER_P(ValueIs, e, "") {
00064 return testing::ExplainMatchResult(e, arg.value(), result_listener);
00065 }
00066
00067
00068
00069
00070
00071 template <typename T>
00072 class InstanceTest : public ::testing::Test {};
00073 TYPED_TEST_SUITE_P(InstanceTest);
00074
00075
00076
00077 class RefCounted {
00078 public:
00079 RefCounted(int value, int* count) : value_(value), count_(count) {
00080 Ref();
00081 }
00082
00083 RefCounted(const RefCounted& v)
00084 : value_(v.value_), count_(v.count_) {
00085 Ref();
00086 }
00087
00088 ~RefCounted() {
00089 Unref();
00090 count_ = nullptr;
00091 }
00092
00093 friend void swap(RefCounted& a, RefCounted& b) {
00094 using std::swap;
00095 swap(a.value_, b.value_);
00096 swap(a.count_, b.count_);
00097 }
00098
00099 RefCounted& operator=(RefCounted v) {
00100 using std::swap;
00101 swap(*this, v);
00102 return *this;
00103 }
00104
00105 void Ref() const {
00106 ABSL_RAW_CHECK(count_ != nullptr, "");
00107 ++(*count_);
00108 }
00109
00110 void Unref() const {
00111 --(*count_);
00112 ABSL_RAW_CHECK(*count_ >= 0, "");
00113 }
00114
00115 int value_;
00116 int* count_;
00117 };
00118
00119 using RefCountedVec = absl::InlinedVector<RefCounted, 8>;
00120
00121
00122 class Dynamic {
00123 public:
00124 virtual ~Dynamic() {}
00125 };
00126
00127 using DynamicVec = absl::InlinedVector<Dynamic, 8>;
00128
00129
00130 template <typename Container>
00131 static void Fill(Container* v, int len, int offset = 0) {
00132 for (int i = 0; i < len; i++) {
00133 v->push_back(i + offset);
00134 }
00135 }
00136
00137 static IntVec Fill(int len, int offset = 0) {
00138 IntVec v;
00139 Fill(&v, len, offset);
00140 return v;
00141 }
00142
00143 TEST(IntVec, SimpleOps) {
00144 for (int len = 0; len < 20; len++) {
00145 IntVec v;
00146 const IntVec& cv = v;
00147
00148 Fill(&v, len);
00149 EXPECT_EQ(len, v.size());
00150 EXPECT_LE(len, v.capacity());
00151
00152 for (int i = 0; i < len; i++) {
00153 EXPECT_EQ(i, v[i]);
00154 EXPECT_EQ(i, v.at(i));
00155 }
00156 EXPECT_EQ(v.begin(), v.data());
00157 EXPECT_EQ(cv.begin(), cv.data());
00158
00159 int counter = 0;
00160 for (IntVec::iterator iter = v.begin(); iter != v.end(); ++iter) {
00161 EXPECT_EQ(counter, *iter);
00162 counter++;
00163 }
00164 EXPECT_EQ(counter, len);
00165
00166 counter = 0;
00167 for (IntVec::const_iterator iter = v.begin(); iter != v.end(); ++iter) {
00168 EXPECT_EQ(counter, *iter);
00169 counter++;
00170 }
00171 EXPECT_EQ(counter, len);
00172
00173 counter = 0;
00174 for (IntVec::const_iterator iter = v.cbegin(); iter != v.cend(); ++iter) {
00175 EXPECT_EQ(counter, *iter);
00176 counter++;
00177 }
00178 EXPECT_EQ(counter, len);
00179
00180 if (len > 0) {
00181 EXPECT_EQ(0, v.front());
00182 EXPECT_EQ(len - 1, v.back());
00183 v.pop_back();
00184 EXPECT_EQ(len - 1, v.size());
00185 for (int i = 0; i < v.size(); ++i) {
00186 EXPECT_EQ(i, v[i]);
00187 EXPECT_EQ(i, v.at(i));
00188 }
00189 }
00190 }
00191 }
00192
00193 TEST(IntVec, AtThrows) {
00194 IntVec v = {1, 2, 3};
00195 EXPECT_EQ(v.at(2), 3);
00196 ABSL_BASE_INTERNAL_EXPECT_FAIL(v.at(3), std::out_of_range,
00197 "failed bounds check");
00198 }
00199
00200 TEST(IntVec, ReverseIterator) {
00201 for (int len = 0; len < 20; len++) {
00202 IntVec v;
00203 Fill(&v, len);
00204
00205 int counter = len;
00206 for (IntVec::reverse_iterator iter = v.rbegin(); iter != v.rend(); ++iter) {
00207 counter--;
00208 EXPECT_EQ(counter, *iter);
00209 }
00210 EXPECT_EQ(counter, 0);
00211
00212 counter = len;
00213 for (IntVec::const_reverse_iterator iter = v.rbegin(); iter != v.rend();
00214 ++iter) {
00215 counter--;
00216 EXPECT_EQ(counter, *iter);
00217 }
00218 EXPECT_EQ(counter, 0);
00219
00220 counter = len;
00221 for (IntVec::const_reverse_iterator iter = v.crbegin(); iter != v.crend();
00222 ++iter) {
00223 counter--;
00224 EXPECT_EQ(counter, *iter);
00225 }
00226 EXPECT_EQ(counter, 0);
00227 }
00228 }
00229
00230 TEST(IntVec, Erase) {
00231 for (int len = 1; len < 20; len++) {
00232 for (int i = 0; i < len; ++i) {
00233 IntVec v;
00234 Fill(&v, len);
00235 v.erase(v.begin() + i);
00236 EXPECT_EQ(len - 1, v.size());
00237 for (int j = 0; j < i; ++j) {
00238 EXPECT_EQ(j, v[j]);
00239 }
00240 for (int j = i; j < len - 1; ++j) {
00241 EXPECT_EQ(j + 1, v[j]);
00242 }
00243 }
00244 }
00245 }
00246
00247
00248
00249
00250 TEST(RefCountedVec, EraseBeginEnd) {
00251 for (int len = 1; len < 20; ++len) {
00252 for (int erase_begin = 0; erase_begin < len; ++erase_begin) {
00253 for (int erase_end = erase_begin; erase_end <= len; ++erase_end) {
00254 std::vector<int> counts(len, 0);
00255 RefCountedVec v;
00256 for (int i = 0; i < len; ++i) {
00257 v.push_back(RefCounted(i, &counts[i]));
00258 }
00259
00260 int erase_len = erase_end - erase_begin;
00261
00262 v.erase(v.begin() + erase_begin, v.begin() + erase_end);
00263
00264 EXPECT_EQ(len - erase_len, v.size());
00265
00266
00267 for (int i = 0; i < erase_begin; ++i) {
00268 EXPECT_EQ(i, v[i].value_);
00269 }
00270
00271
00272 for (int i = erase_begin; i < v.size(); ++i) {
00273 EXPECT_EQ(i + erase_len, v[i].value_);
00274 }
00275
00276
00277 for (int i = 0; i < erase_begin; ++i) {
00278 EXPECT_EQ(1, counts[i]);
00279 }
00280
00281
00282 for (int i = erase_begin; i < erase_end; ++i) {
00283 EXPECT_EQ(0, counts[i]);
00284 }
00285
00286
00287 for (int i = erase_end; i< len; ++i) {
00288 EXPECT_EQ(1, counts[i]);
00289 }
00290 }
00291 }
00292 }
00293 }
00294
00295 struct NoDefaultCtor {
00296 explicit NoDefaultCtor(int) {}
00297 };
00298 struct NoCopy {
00299 NoCopy() {}
00300 NoCopy(const NoCopy&) = delete;
00301 };
00302 struct NoAssign {
00303 NoAssign() {}
00304 NoAssign& operator=(const NoAssign&) = delete;
00305 };
00306 struct MoveOnly {
00307 MoveOnly() {}
00308 MoveOnly(MoveOnly&&) = default;
00309 MoveOnly& operator=(MoveOnly&&) = default;
00310 };
00311 TEST(InlinedVectorTest, NoDefaultCtor) {
00312 absl::InlinedVector<NoDefaultCtor, 1> v(10, NoDefaultCtor(2));
00313 (void)v;
00314 }
00315 TEST(InlinedVectorTest, NoCopy) {
00316 absl::InlinedVector<NoCopy, 1> v(10);
00317 (void)v;
00318 }
00319 TEST(InlinedVectorTest, NoAssign) {
00320 absl::InlinedVector<NoAssign, 1> v(10);
00321 (void)v;
00322 }
00323 TEST(InlinedVectorTest, MoveOnly) {
00324 absl::InlinedVector<MoveOnly, 2> v;
00325 v.push_back(MoveOnly{});
00326 v.push_back(MoveOnly{});
00327 v.push_back(MoveOnly{});
00328 v.erase(v.begin());
00329 v.push_back(MoveOnly{});
00330 v.erase(v.begin(), v.begin() + 1);
00331 v.insert(v.begin(), MoveOnly{});
00332 v.emplace(v.begin());
00333 v.emplace(v.begin(), MoveOnly{});
00334 }
00335 TEST(InlinedVectorTest, Noexcept) {
00336 EXPECT_TRUE(std::is_nothrow_move_constructible<IntVec>::value);
00337 EXPECT_TRUE((std::is_nothrow_move_constructible<
00338 absl::InlinedVector<MoveOnly, 2>>::value));
00339
00340 struct MoveCanThrow {
00341 MoveCanThrow(MoveCanThrow&&) {}
00342 };
00343 EXPECT_EQ(absl::default_allocator_is_nothrow::value,
00344 (std::is_nothrow_move_constructible<
00345 absl::InlinedVector<MoveCanThrow, 2>>::value));
00346 }
00347
00348 TEST(InlinedVectorTest, EmplaceBack) {
00349 absl::InlinedVector<std::pair<std::string, int>, 1> v;
00350
00351 auto& inlined_element = v.emplace_back("answer", 42);
00352 EXPECT_EQ(&inlined_element, &v[0]);
00353 EXPECT_EQ(inlined_element.first, "answer");
00354 EXPECT_EQ(inlined_element.second, 42);
00355
00356 auto& allocated_element = v.emplace_back("taxicab", 1729);
00357 EXPECT_EQ(&allocated_element, &v[1]);
00358 EXPECT_EQ(allocated_element.first, "taxicab");
00359 EXPECT_EQ(allocated_element.second, 1729);
00360 }
00361
00362 TEST(InlinedVectorTest, ShrinkToFitGrowingVector) {
00363 absl::InlinedVector<std::pair<std::string, int>, 1> v;
00364
00365 v.shrink_to_fit();
00366 EXPECT_EQ(v.capacity(), 1);
00367
00368 v.emplace_back("answer", 42);
00369 v.shrink_to_fit();
00370 EXPECT_EQ(v.capacity(), 1);
00371
00372 v.emplace_back("taxicab", 1729);
00373 EXPECT_GE(v.capacity(), 2);
00374 v.shrink_to_fit();
00375 EXPECT_EQ(v.capacity(), 2);
00376
00377 v.reserve(100);
00378 EXPECT_GE(v.capacity(), 100);
00379 v.shrink_to_fit();
00380 EXPECT_EQ(v.capacity(), 2);
00381 }
00382
00383 TEST(InlinedVectorTest, ShrinkToFitEdgeCases) {
00384 {
00385 absl::InlinedVector<std::pair<std::string, int>, 1> v;
00386 v.emplace_back("answer", 42);
00387 v.emplace_back("taxicab", 1729);
00388 EXPECT_GE(v.capacity(), 2);
00389 v.pop_back();
00390 v.shrink_to_fit();
00391 EXPECT_EQ(v.capacity(), 1);
00392 EXPECT_EQ(v[0].first, "answer");
00393 EXPECT_EQ(v[0].second, 42);
00394 }
00395
00396 {
00397 absl::InlinedVector<std::string, 2> v(100);
00398 v.resize(0);
00399 v.shrink_to_fit();
00400 EXPECT_EQ(v.capacity(), 2);
00401 }
00402
00403 {
00404 absl::InlinedVector<std::string, 2> v(100);
00405 v.resize(1);
00406 v.shrink_to_fit();
00407 EXPECT_EQ(v.capacity(), 2);
00408 }
00409
00410 {
00411 absl::InlinedVector<std::string, 2> v(100);
00412 v.resize(2);
00413 v.shrink_to_fit();
00414 EXPECT_EQ(v.capacity(), 2);
00415 }
00416
00417 {
00418 absl::InlinedVector<std::string, 2> v(100);
00419 v.resize(3);
00420 v.shrink_to_fit();
00421 EXPECT_EQ(v.capacity(), 3);
00422 }
00423 }
00424
00425 TEST(IntVec, Insert) {
00426 for (int len = 0; len < 20; len++) {
00427 for (int pos = 0; pos <= len; pos++) {
00428 {
00429
00430 std::vector<int> std_v;
00431 Fill(&std_v, len);
00432 IntVec v;
00433 Fill(&v, len);
00434
00435 std_v.insert(std_v.begin() + pos, 9999);
00436 IntVec::iterator it = v.insert(v.cbegin() + pos, 9999);
00437 EXPECT_THAT(v, ElementsAreArray(std_v));
00438 EXPECT_EQ(it, v.cbegin() + pos);
00439 }
00440 {
00441
00442 std::vector<int> std_v;
00443 Fill(&std_v, len);
00444 IntVec v;
00445 Fill(&v, len);
00446
00447 IntVec::size_type n = 5;
00448 std_v.insert(std_v.begin() + pos, n, 9999);
00449 IntVec::iterator it = v.insert(v.cbegin() + pos, n, 9999);
00450 EXPECT_THAT(v, ElementsAreArray(std_v));
00451 EXPECT_EQ(it, v.cbegin() + pos);
00452 }
00453 {
00454
00455 std::vector<int> std_v;
00456 Fill(&std_v, len);
00457 IntVec v;
00458 Fill(&v, len);
00459
00460 const std::vector<int> input = {9999, 8888, 7777};
00461 std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend());
00462 IntVec::iterator it =
00463 v.insert(v.cbegin() + pos, input.cbegin(), input.cend());
00464 EXPECT_THAT(v, ElementsAreArray(std_v));
00465 EXPECT_EQ(it, v.cbegin() + pos);
00466 }
00467 {
00468
00469 std::vector<int> std_v;
00470 Fill(&std_v, len);
00471 IntVec v;
00472 Fill(&v, len);
00473
00474 const std::forward_list<int> input = {9999, 8888, 7777};
00475 std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend());
00476 IntVec::iterator it =
00477 v.insert(v.cbegin() + pos, input.cbegin(), input.cend());
00478 EXPECT_THAT(v, ElementsAreArray(std_v));
00479 EXPECT_EQ(it, v.cbegin() + pos);
00480 }
00481 {
00482
00483 std::vector<int> std_v;
00484 Fill(&std_v, len);
00485 IntVec v;
00486 Fill(&v, len);
00487
00488 std_v.insert(std_v.begin() + pos, {9999, 8888, 7777});
00489 std::istringstream input("9999 8888 7777");
00490 IntVec::iterator it =
00491 v.insert(v.cbegin() + pos, std::istream_iterator<int>(input),
00492 std::istream_iterator<int>());
00493 EXPECT_THAT(v, ElementsAreArray(std_v));
00494 EXPECT_EQ(it, v.cbegin() + pos);
00495 }
00496 {
00497
00498 std::vector<int> std_v;
00499 Fill(&std_v, len);
00500 IntVec v;
00501 Fill(&v, len);
00502
00503 std_v.insert(std_v.begin() + pos, {9999, 8888});
00504 IntVec::iterator it = v.insert(v.cbegin() + pos, {9999, 8888});
00505 EXPECT_THAT(v, ElementsAreArray(std_v));
00506 EXPECT_EQ(it, v.cbegin() + pos);
00507 }
00508 }
00509 }
00510 }
00511
00512 TEST(RefCountedVec, InsertConstructorDestructor) {
00513
00514
00515 for (int len = 0; len < 20; len++) {
00516 SCOPED_TRACE(len);
00517 for (int pos = 0; pos <= len; pos++) {
00518 SCOPED_TRACE(pos);
00519 std::vector<int> counts(len, 0);
00520 int inserted_count = 0;
00521 RefCountedVec v;
00522 for (int i = 0; i < len; ++i) {
00523 SCOPED_TRACE(i);
00524 v.push_back(RefCounted(i, &counts[i]));
00525 }
00526
00527 EXPECT_THAT(counts, Each(Eq(1)));
00528
00529 RefCounted insert_element(9999, &inserted_count);
00530 EXPECT_EQ(1, inserted_count);
00531 v.insert(v.begin() + pos, insert_element);
00532 EXPECT_EQ(2, inserted_count);
00533
00534 EXPECT_THAT(counts, Each(Eq(1)));
00535 EXPECT_EQ(2, inserted_count);
00536 }
00537 }
00538 }
00539
00540 TEST(IntVec, Resize) {
00541 for (int len = 0; len < 20; len++) {
00542 IntVec v;
00543 Fill(&v, len);
00544
00545
00546 static const int kResizeElem = 1000000;
00547 for (int k = 0; k < 10; k++) {
00548
00549 v.resize(len+k, kResizeElem);
00550 EXPECT_EQ(len+k, v.size());
00551 EXPECT_LE(len+k, v.capacity());
00552 for (int i = 0; i < len+k; i++) {
00553 if (i < len) {
00554 EXPECT_EQ(i, v[i]);
00555 } else {
00556 EXPECT_EQ(kResizeElem, v[i]);
00557 }
00558 }
00559
00560
00561 v.resize(len, kResizeElem);
00562 EXPECT_EQ(len, v.size());
00563 EXPECT_LE(len, v.capacity());
00564 for (int i = 0; i < len; i++) {
00565 EXPECT_EQ(i, v[i]);
00566 }
00567 }
00568 }
00569 }
00570
00571 TEST(IntVec, InitWithLength) {
00572 for (int len = 0; len < 20; len++) {
00573 IntVec v(len, 7);
00574 EXPECT_EQ(len, v.size());
00575 EXPECT_LE(len, v.capacity());
00576 for (int i = 0; i < len; i++) {
00577 EXPECT_EQ(7, v[i]);
00578 }
00579 }
00580 }
00581
00582 TEST(IntVec, CopyConstructorAndAssignment) {
00583 for (int len = 0; len < 20; len++) {
00584 IntVec v;
00585 Fill(&v, len);
00586 EXPECT_EQ(len, v.size());
00587 EXPECT_LE(len, v.capacity());
00588
00589 IntVec v2(v);
00590 EXPECT_TRUE(v == v2) << PrintToString(v) << PrintToString(v2);
00591
00592 for (int start_len = 0; start_len < 20; start_len++) {
00593 IntVec v3;
00594 Fill(&v3, start_len, 99);
00595 v3 = v;
00596 EXPECT_TRUE(v == v3) << PrintToString(v) << PrintToString(v3);
00597 }
00598 }
00599 }
00600
00601 TEST(IntVec, AliasingCopyAssignment) {
00602 for (int len = 0; len < 20; ++len) {
00603 IntVec original;
00604 Fill(&original, len);
00605 IntVec dup = original;
00606 dup = *&dup;
00607 EXPECT_EQ(dup, original);
00608 }
00609 }
00610
00611 TEST(IntVec, MoveConstructorAndAssignment) {
00612 for (int len = 0; len < 20; len++) {
00613 IntVec v_in;
00614 const int inlined_capacity = v_in.capacity();
00615 Fill(&v_in, len);
00616 EXPECT_EQ(len, v_in.size());
00617 EXPECT_LE(len, v_in.capacity());
00618
00619 {
00620 IntVec v_temp(v_in);
00621 auto* old_data = v_temp.data();
00622 IntVec v_out(std::move(v_temp));
00623 EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out);
00624 if (v_in.size() > inlined_capacity) {
00625
00626 EXPECT_TRUE(v_out.data() == old_data);
00627 } else {
00628 EXPECT_FALSE(v_out.data() == old_data);
00629 }
00630 }
00631 for (int start_len = 0; start_len < 20; start_len++) {
00632 IntVec v_out;
00633 Fill(&v_out, start_len, 99);
00634 IntVec v_temp(v_in);
00635 auto* old_data = v_temp.data();
00636 v_out = std::move(v_temp);
00637 EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out);
00638 if (v_in.size() > inlined_capacity) {
00639
00640 EXPECT_TRUE(v_out.data() == old_data);
00641 } else {
00642 EXPECT_FALSE(v_out.data() == old_data);
00643 }
00644 }
00645 }
00646 }
00647
00648 class NotTriviallyDestructible {
00649 public:
00650 NotTriviallyDestructible() : p_(new int(1)) {}
00651 explicit NotTriviallyDestructible(int i) : p_(new int(i)) {}
00652
00653 NotTriviallyDestructible(const NotTriviallyDestructible& other)
00654 : p_(new int(*other.p_)) {}
00655
00656 NotTriviallyDestructible& operator=(const NotTriviallyDestructible& other) {
00657 p_ = absl::make_unique<int>(*other.p_);
00658 return *this;
00659 }
00660
00661 bool operator==(const NotTriviallyDestructible& other) const {
00662 return *p_ == *other.p_;
00663 }
00664
00665 private:
00666 std::unique_ptr<int> p_;
00667 };
00668
00669 TEST(AliasingTest, Emplace) {
00670 for (int i = 2; i < 20; ++i) {
00671 absl::InlinedVector<NotTriviallyDestructible, 10> vec;
00672 for (int j = 0; j < i; ++j) {
00673 vec.push_back(NotTriviallyDestructible(j));
00674 }
00675 vec.emplace(vec.begin(), vec[0]);
00676 EXPECT_EQ(vec[0], vec[1]);
00677 vec.emplace(vec.begin() + i / 2, vec[i / 2]);
00678 EXPECT_EQ(vec[i / 2], vec[i / 2 + 1]);
00679 vec.emplace(vec.end() - 1, vec.back());
00680 EXPECT_EQ(vec[vec.size() - 2], vec.back());
00681 }
00682 }
00683
00684 TEST(AliasingTest, InsertWithCount) {
00685 for (int i = 1; i < 20; ++i) {
00686 absl::InlinedVector<NotTriviallyDestructible, 10> vec;
00687 for (int j = 0; j < i; ++j) {
00688 vec.push_back(NotTriviallyDestructible(j));
00689 }
00690 for (int n = 0; n < 5; ++n) {
00691
00692 vec.insert(vec.begin(), n, vec.back());
00693 auto b = vec.begin();
00694 EXPECT_TRUE(
00695 std::all_of(b, b + n, [&vec](const NotTriviallyDestructible& x) {
00696 return x == vec.back();
00697 }));
00698
00699 auto m_idx = vec.size() / 2;
00700 vec.insert(vec.begin() + m_idx, n, vec.back());
00701 auto m = vec.begin() + m_idx;
00702 EXPECT_TRUE(
00703 std::all_of(m, m + n, [&vec](const NotTriviallyDestructible& x) {
00704 return x == vec.back();
00705 }));
00706
00707
00708
00709 auto old_e = vec.size() - 1;
00710 auto val = vec[old_e];
00711 vec.insert(vec.end(), n, vec[old_e]);
00712 auto e = vec.begin() + old_e;
00713 EXPECT_TRUE(std::all_of(
00714 e, e + n,
00715 [&val](const NotTriviallyDestructible& x) { return x == val; }));
00716 }
00717 }
00718 }
00719
00720 TEST(OverheadTest, Storage) {
00721
00722
00723
00724
00725 EXPECT_EQ(2 * sizeof(int*),
00726 sizeof(absl::InlinedVector<int*, 1>) - 1 * sizeof(int*));
00727 EXPECT_EQ(1 * sizeof(int*),
00728 sizeof(absl::InlinedVector<int*, 2>) - 2 * sizeof(int*));
00729 EXPECT_EQ(1 * sizeof(int*),
00730 sizeof(absl::InlinedVector<int*, 3>) - 3 * sizeof(int*));
00731 EXPECT_EQ(1 * sizeof(int*),
00732 sizeof(absl::InlinedVector<int*, 4>) - 4 * sizeof(int*));
00733 EXPECT_EQ(1 * sizeof(int*),
00734 sizeof(absl::InlinedVector<int*, 5>) - 5 * sizeof(int*));
00735 EXPECT_EQ(1 * sizeof(int*),
00736 sizeof(absl::InlinedVector<int*, 6>) - 6 * sizeof(int*));
00737 EXPECT_EQ(1 * sizeof(int*),
00738 sizeof(absl::InlinedVector<int*, 7>) - 7 * sizeof(int*));
00739 EXPECT_EQ(1 * sizeof(int*),
00740 sizeof(absl::InlinedVector<int*, 8>) - 8 * sizeof(int*));
00741 }
00742
00743 TEST(IntVec, Clear) {
00744 for (int len = 0; len < 20; len++) {
00745 SCOPED_TRACE(len);
00746 IntVec v;
00747 Fill(&v, len);
00748 v.clear();
00749 EXPECT_EQ(0, v.size());
00750 EXPECT_EQ(v.begin(), v.end());
00751 }
00752 }
00753
00754 TEST(IntVec, Reserve) {
00755 for (int len = 0; len < 20; len++) {
00756 IntVec v;
00757 Fill(&v, len);
00758
00759 for (int newlen = 0; newlen < 100; newlen++) {
00760 const int* start_rep = v.data();
00761 v.reserve(newlen);
00762 const int* final_rep = v.data();
00763 if (newlen <= len) {
00764 EXPECT_EQ(start_rep, final_rep);
00765 }
00766 EXPECT_LE(newlen, v.capacity());
00767
00768
00769 while (v.size() < newlen) {
00770 v.push_back(0);
00771 }
00772 EXPECT_EQ(final_rep, v.data());
00773 }
00774 }
00775 }
00776
00777 TEST(StringVec, SelfRefPushBack) {
00778 std::vector<std::string> std_v;
00779 absl::InlinedVector<std::string, 4> v;
00780 const std::string s = "A quite long std::string to ensure heap.";
00781 std_v.push_back(s);
00782 v.push_back(s);
00783 for (int i = 0; i < 20; ++i) {
00784 EXPECT_THAT(v, ElementsAreArray(std_v));
00785
00786 v.push_back(v.back());
00787 std_v.push_back(std_v.back());
00788 }
00789 EXPECT_THAT(v, ElementsAreArray(std_v));
00790 }
00791
00792 TEST(StringVec, SelfRefPushBackWithMove) {
00793 std::vector<std::string> std_v;
00794 absl::InlinedVector<std::string, 4> v;
00795 const std::string s = "A quite long std::string to ensure heap.";
00796 std_v.push_back(s);
00797 v.push_back(s);
00798 for (int i = 0; i < 20; ++i) {
00799 EXPECT_EQ(v.back(), std_v.back());
00800
00801 v.push_back(std::move(v.back()));
00802 std_v.push_back(std::move(std_v.back()));
00803 }
00804 EXPECT_EQ(v.back(), std_v.back());
00805 }
00806
00807 TEST(StringVec, SelfMove) {
00808 const std::string s = "A quite long std::string to ensure heap.";
00809 for (int len = 0; len < 20; len++) {
00810 SCOPED_TRACE(len);
00811 absl::InlinedVector<std::string, 8> v;
00812 for (int i = 0; i < len; ++i) {
00813 SCOPED_TRACE(i);
00814 v.push_back(s);
00815 }
00816
00817 v = std::move(*(&v));
00818
00819
00820
00821 std::vector<std::string> copy(v.begin(), v.end());
00822 }
00823 }
00824
00825 TEST(IntVec, Swap) {
00826 for (int l1 = 0; l1 < 20; l1++) {
00827 SCOPED_TRACE(l1);
00828 for (int l2 = 0; l2 < 20; l2++) {
00829 SCOPED_TRACE(l2);
00830 IntVec a = Fill(l1, 0);
00831 IntVec b = Fill(l2, 100);
00832 {
00833 using std::swap;
00834 swap(a, b);
00835 }
00836 EXPECT_EQ(l1, b.size());
00837 EXPECT_EQ(l2, a.size());
00838 for (int i = 0; i < l1; i++) {
00839 SCOPED_TRACE(i);
00840 EXPECT_EQ(i, b[i]);
00841 }
00842 for (int i = 0; i < l2; i++) {
00843 SCOPED_TRACE(i);
00844 EXPECT_EQ(100 + i, a[i]);
00845 }
00846 }
00847 }
00848 }
00849
00850 TYPED_TEST_P(InstanceTest, Swap) {
00851 using Instance = TypeParam;
00852 using InstanceVec = absl::InlinedVector<Instance, 8>;
00853 for (int l1 = 0; l1 < 20; l1++) {
00854 SCOPED_TRACE(l1);
00855 for (int l2 = 0; l2 < 20; l2++) {
00856 SCOPED_TRACE(l2);
00857 InstanceTracker tracker;
00858 InstanceVec a, b;
00859 const size_t inlined_capacity = a.capacity();
00860 auto min_len = std::min(l1, l2);
00861 auto max_len = std::max(l1, l2);
00862 for (int i = 0; i < l1; i++) a.push_back(Instance(i));
00863 for (int i = 0; i < l2; i++) b.push_back(Instance(100+i));
00864 EXPECT_EQ(tracker.instances(), l1 + l2);
00865 tracker.ResetCopiesMovesSwaps();
00866 {
00867 using std::swap;
00868 swap(a, b);
00869 }
00870 EXPECT_EQ(tracker.instances(), l1 + l2);
00871 if (a.size() > inlined_capacity && b.size() > inlined_capacity) {
00872 EXPECT_EQ(tracker.swaps(), 0);
00873 EXPECT_EQ(tracker.moves(), 0);
00874 } else if (a.size() <= inlined_capacity && b.size() <= inlined_capacity) {
00875 EXPECT_EQ(tracker.swaps(), min_len);
00876 EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()),
00877 max_len - min_len);
00878 } else {
00879
00880
00881 EXPECT_EQ(tracker.swaps(), 0);
00882 EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()),
00883 min_len);
00884 }
00885
00886 EXPECT_EQ(l1, b.size());
00887 EXPECT_EQ(l2, a.size());
00888 for (int i = 0; i < l1; i++) {
00889 EXPECT_EQ(i, b[i].value());
00890 }
00891 for (int i = 0; i < l2; i++) {
00892 EXPECT_EQ(100 + i, a[i].value());
00893 }
00894 }
00895 }
00896 }
00897
00898 TEST(IntVec, EqualAndNotEqual) {
00899 IntVec a, b;
00900 EXPECT_TRUE(a == b);
00901 EXPECT_FALSE(a != b);
00902
00903 a.push_back(3);
00904 EXPECT_FALSE(a == b);
00905 EXPECT_TRUE(a != b);
00906
00907 b.push_back(3);
00908 EXPECT_TRUE(a == b);
00909 EXPECT_FALSE(a != b);
00910
00911 b.push_back(7);
00912 EXPECT_FALSE(a == b);
00913 EXPECT_TRUE(a != b);
00914
00915 a.push_back(6);
00916 EXPECT_FALSE(a == b);
00917 EXPECT_TRUE(a != b);
00918
00919 a.clear();
00920 b.clear();
00921 for (int i = 0; i < 100; i++) {
00922 a.push_back(i);
00923 b.push_back(i);
00924 EXPECT_TRUE(a == b);
00925 EXPECT_FALSE(a != b);
00926
00927 b[i] = b[i] + 1;
00928 EXPECT_FALSE(a == b);
00929 EXPECT_TRUE(a != b);
00930
00931 b[i] = b[i] - 1;
00932 EXPECT_TRUE(a == b);
00933 EXPECT_FALSE(a != b);
00934 }
00935 }
00936
00937 TEST(IntVec, RelationalOps) {
00938 IntVec a, b;
00939 EXPECT_FALSE(a < b);
00940 EXPECT_FALSE(b < a);
00941 EXPECT_FALSE(a > b);
00942 EXPECT_FALSE(b > a);
00943 EXPECT_TRUE(a <= b);
00944 EXPECT_TRUE(b <= a);
00945 EXPECT_TRUE(a >= b);
00946 EXPECT_TRUE(b >= a);
00947 b.push_back(3);
00948 EXPECT_TRUE(a < b);
00949 EXPECT_FALSE(b < a);
00950 EXPECT_FALSE(a > b);
00951 EXPECT_TRUE(b > a);
00952 EXPECT_TRUE(a <= b);
00953 EXPECT_FALSE(b <= a);
00954 EXPECT_FALSE(a >= b);
00955 EXPECT_TRUE(b >= a);
00956 }
00957
00958 TYPED_TEST_P(InstanceTest, CountConstructorsDestructors) {
00959 using Instance = TypeParam;
00960 using InstanceVec = absl::InlinedVector<Instance, 8>;
00961 InstanceTracker tracker;
00962 for (int len = 0; len < 20; len++) {
00963 SCOPED_TRACE(len);
00964 tracker.ResetCopiesMovesSwaps();
00965
00966 InstanceVec v;
00967 const size_t inlined_capacity = v.capacity();
00968 for (int i = 0; i < len; i++) {
00969 v.push_back(Instance(i));
00970 }
00971 EXPECT_EQ(tracker.instances(), len);
00972 EXPECT_GE(tracker.copies() + tracker.moves(),
00973 len);
00974 tracker.ResetCopiesMovesSwaps();
00975
00976
00977 tracker.ResetCopiesMovesSwaps();
00978 v.resize(len + 10, Instance(100));
00979 EXPECT_EQ(tracker.instances(), len + 10);
00980 if (len <= inlined_capacity && len + 10 > inlined_capacity) {
00981 EXPECT_EQ(tracker.copies() + tracker.moves(), 10 + len);
00982 } else {
00983
00984
00985 EXPECT_GE(tracker.copies() + tracker.moves(),
00986 10);
00987 }
00988
00989
00990 tracker.ResetCopiesMovesSwaps();
00991 v.resize(len, Instance(100));
00992 EXPECT_EQ(tracker.instances(), len);
00993 EXPECT_EQ(tracker.copies(), 0);
00994 EXPECT_EQ(tracker.moves(), 0);
00995
00996
00997 SCOPED_TRACE("reserve");
00998 v.reserve(len+1000);
00999 EXPECT_EQ(tracker.instances(), len);
01000 EXPECT_EQ(tracker.copies() + tracker.moves(), len);
01001
01002
01003 if (len > 0) {
01004 tracker.ResetCopiesMovesSwaps();
01005 v.pop_back();
01006 EXPECT_EQ(tracker.instances(), len - 1);
01007 EXPECT_EQ(tracker.copies(), 0);
01008 EXPECT_EQ(tracker.moves(), 0);
01009
01010 if (!v.empty()) {
01011 tracker.ResetCopiesMovesSwaps();
01012 v.erase(v.begin());
01013 EXPECT_EQ(tracker.instances(), len - 2);
01014 EXPECT_EQ(tracker.copies() + tracker.moves(), len - 2);
01015 }
01016 }
01017
01018 tracker.ResetCopiesMovesSwaps();
01019 int instances_before_empty_erase = tracker.instances();
01020 v.erase(v.begin(), v.begin());
01021 EXPECT_EQ(tracker.instances(), instances_before_empty_erase);
01022 EXPECT_EQ(tracker.copies() + tracker.moves(), 0);
01023 }
01024 }
01025
01026 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnCopyConstruction) {
01027 using Instance = TypeParam;
01028 using InstanceVec = absl::InlinedVector<Instance, 8>;
01029 InstanceTracker tracker;
01030 for (int len = 0; len < 20; len++) {
01031 SCOPED_TRACE(len);
01032 tracker.ResetCopiesMovesSwaps();
01033
01034 InstanceVec v;
01035 for (int i = 0; i < len; i++) {
01036 v.push_back(Instance(i));
01037 }
01038 EXPECT_EQ(tracker.instances(), len);
01039 EXPECT_GE(tracker.copies() + tracker.moves(),
01040 len);
01041 tracker.ResetCopiesMovesSwaps();
01042 {
01043 InstanceVec v_copy(v);
01044 EXPECT_EQ(tracker.instances(), len + len);
01045 EXPECT_EQ(tracker.copies(), len);
01046 EXPECT_EQ(tracker.moves(), 0);
01047 }
01048 EXPECT_EQ(tracker.instances(), len);
01049 }
01050 }
01051
01052 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveConstruction) {
01053 using Instance = TypeParam;
01054 using InstanceVec = absl::InlinedVector<Instance, 8>;
01055 InstanceTracker tracker;
01056 for (int len = 0; len < 20; len++) {
01057 SCOPED_TRACE(len);
01058 tracker.ResetCopiesMovesSwaps();
01059
01060 InstanceVec v;
01061 const size_t inlined_capacity = v.capacity();
01062 for (int i = 0; i < len; i++) {
01063 v.push_back(Instance(i));
01064 }
01065 EXPECT_EQ(tracker.instances(), len);
01066 EXPECT_GE(tracker.copies() + tracker.moves(),
01067 len);
01068 tracker.ResetCopiesMovesSwaps();
01069 {
01070 InstanceVec v_copy(std::move(v));
01071 if (len > inlined_capacity) {
01072
01073 EXPECT_EQ(tracker.instances(), len);
01074 EXPECT_EQ(tracker.live_instances(), len);
01075
01076 EXPECT_EQ(v.size(), 0);
01077 EXPECT_EQ(tracker.copies(), 0);
01078 EXPECT_EQ(tracker.moves(), 0);
01079 } else {
01080 EXPECT_EQ(tracker.instances(), len + len);
01081 if (Instance::supports_move()) {
01082 EXPECT_EQ(tracker.live_instances(), len);
01083 EXPECT_EQ(tracker.copies(), 0);
01084 EXPECT_EQ(tracker.moves(), len);
01085 } else {
01086 EXPECT_EQ(tracker.live_instances(), len + len);
01087 EXPECT_EQ(tracker.copies(), len);
01088 EXPECT_EQ(tracker.moves(), 0);
01089 }
01090 }
01091 EXPECT_EQ(tracker.swaps(), 0);
01092 }
01093 }
01094 }
01095
01096 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnAssignment) {
01097 using Instance = TypeParam;
01098 using InstanceVec = absl::InlinedVector<Instance, 8>;
01099 InstanceTracker tracker;
01100 for (int len = 0; len < 20; len++) {
01101 SCOPED_TRACE(len);
01102 for (int longorshort = 0; longorshort <= 1; ++longorshort) {
01103 SCOPED_TRACE(longorshort);
01104 tracker.ResetCopiesMovesSwaps();
01105
01106 InstanceVec longer, shorter;
01107 for (int i = 0; i < len; i++) {
01108 longer.push_back(Instance(i));
01109 shorter.push_back(Instance(i));
01110 }
01111 longer.push_back(Instance(len));
01112 EXPECT_EQ(tracker.instances(), len + len + 1);
01113 EXPECT_GE(tracker.copies() + tracker.moves(),
01114 len + len + 1);
01115
01116 tracker.ResetCopiesMovesSwaps();
01117 if (longorshort) {
01118 shorter = longer;
01119 EXPECT_EQ(tracker.instances(), (len + 1) + (len + 1));
01120 EXPECT_GE(tracker.copies() + tracker.moves(),
01121 len + 1);
01122 } else {
01123 longer = shorter;
01124 EXPECT_EQ(tracker.instances(), len + len);
01125 EXPECT_EQ(tracker.copies() + tracker.moves(), len);
01126 }
01127 }
01128 }
01129 }
01130
01131 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveAssignment) {
01132 using Instance = TypeParam;
01133 using InstanceVec = absl::InlinedVector<Instance, 8>;
01134 InstanceTracker tracker;
01135 for (int len = 0; len < 20; len++) {
01136 SCOPED_TRACE(len);
01137 for (int longorshort = 0; longorshort <= 1; ++longorshort) {
01138 SCOPED_TRACE(longorshort);
01139 tracker.ResetCopiesMovesSwaps();
01140
01141 InstanceVec longer, shorter;
01142 const int inlined_capacity = longer.capacity();
01143 for (int i = 0; i < len; i++) {
01144 longer.push_back(Instance(i));
01145 shorter.push_back(Instance(i));
01146 }
01147 longer.push_back(Instance(len));
01148 EXPECT_EQ(tracker.instances(), len + len + 1);
01149 EXPECT_GE(tracker.copies() + tracker.moves(),
01150 len + len + 1);
01151
01152 tracker.ResetCopiesMovesSwaps();
01153 int src_len;
01154 if (longorshort) {
01155 src_len = len + 1;
01156 shorter = std::move(longer);
01157 } else {
01158 src_len = len;
01159 longer = std::move(shorter);
01160 }
01161 if (src_len > inlined_capacity) {
01162
01163 EXPECT_EQ(tracker.instances(), src_len);
01164 EXPECT_EQ(tracker.live_instances(), src_len);
01165 EXPECT_EQ(tracker.copies(), 0);
01166 EXPECT_EQ(tracker.moves(), 0);
01167 } else {
01168
01169 EXPECT_EQ(tracker.instances(), src_len + src_len);
01170 if (Instance::supports_move()) {
01171 EXPECT_EQ(tracker.copies(), 0);
01172 EXPECT_EQ(tracker.moves(), src_len);
01173 EXPECT_EQ(tracker.live_instances(), src_len);
01174 } else {
01175 EXPECT_EQ(tracker.copies(), src_len);
01176 EXPECT_EQ(tracker.moves(), 0);
01177 EXPECT_EQ(tracker.live_instances(), src_len + src_len);
01178 }
01179 }
01180 EXPECT_EQ(tracker.swaps(), 0);
01181 }
01182 }
01183 }
01184
01185 TEST(CountElemAssign, SimpleTypeWithInlineBacking) {
01186 for (size_t original_size = 0; original_size <= 5; ++original_size) {
01187 SCOPED_TRACE(original_size);
01188
01189 std::vector<int> original_contents(original_size, 12345);
01190
01191 absl::InlinedVector<int, 2> v(original_contents.begin(),
01192 original_contents.end());
01193 v.assign(2, 123);
01194 EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(123, 123)));
01195 if (original_size <= 2) {
01196
01197 EXPECT_EQ(2, v.capacity());
01198 }
01199 }
01200 }
01201
01202 TEST(CountElemAssign, SimpleTypeWithAllocation) {
01203 for (size_t original_size = 0; original_size <= 5; ++original_size) {
01204 SCOPED_TRACE(original_size);
01205
01206 std::vector<int> original_contents(original_size, 12345);
01207
01208 absl::InlinedVector<int, 2> v(original_contents.begin(),
01209 original_contents.end());
01210 v.assign(3, 123);
01211 EXPECT_THAT(v, AllOf(SizeIs(3), ElementsAre(123, 123, 123)));
01212 EXPECT_LE(v.size(), v.capacity());
01213 }
01214 }
01215
01216 TYPED_TEST_P(InstanceTest, CountElemAssignInlineBacking) {
01217 using Instance = TypeParam;
01218 for (size_t original_size = 0; original_size <= 5; ++original_size) {
01219 SCOPED_TRACE(original_size);
01220
01221 std::vector<Instance> original_contents(original_size, Instance(12345));
01222
01223 absl::InlinedVector<Instance, 2> v(original_contents.begin(),
01224 original_contents.end());
01225 v.assign(2, Instance(123));
01226 EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(ValueIs(123), ValueIs(123))));
01227 if (original_size <= 2) {
01228
01229 EXPECT_EQ(2, v.capacity());
01230 }
01231 }
01232 }
01233
01234 template <typename Instance>
01235 void InstanceCountElemAssignWithAllocationTest() {
01236 for (size_t original_size = 0; original_size <= 5; ++original_size) {
01237 SCOPED_TRACE(original_size);
01238
01239 std::vector<Instance> original_contents(original_size, Instance(12345));
01240
01241 absl::InlinedVector<Instance, 2> v(original_contents.begin(),
01242 original_contents.end());
01243 v.assign(3, Instance(123));
01244 EXPECT_THAT(v,
01245 AllOf(SizeIs(3),
01246 ElementsAre(ValueIs(123), ValueIs(123), ValueIs(123))));
01247 EXPECT_LE(v.size(), v.capacity());
01248 }
01249 }
01250 TEST(CountElemAssign, WithAllocationCopyableInstance) {
01251 InstanceCountElemAssignWithAllocationTest<CopyableOnlyInstance>();
01252 }
01253 TEST(CountElemAssign, WithAllocationCopyableMovableInstance) {
01254 InstanceCountElemAssignWithAllocationTest<CopyableMovableInstance>();
01255 }
01256
01257 TEST(RangedConstructor, SimpleType) {
01258 std::vector<int> source_v = {4, 5, 6};
01259
01260 absl::InlinedVector<int, 4> v(source_v.begin(), source_v.end());
01261 EXPECT_EQ(3, v.size());
01262 EXPECT_EQ(4, v.capacity());
01263 EXPECT_EQ(4, v[0]);
01264 EXPECT_EQ(5, v[1]);
01265 EXPECT_EQ(6, v[2]);
01266
01267
01268 absl::InlinedVector<int, 2> realloc_v(source_v.begin(), source_v.end());
01269 EXPECT_EQ(3, realloc_v.size());
01270 EXPECT_LT(2, realloc_v.capacity());
01271 EXPECT_EQ(4, realloc_v[0]);
01272 EXPECT_EQ(5, realloc_v[1]);
01273 EXPECT_EQ(6, realloc_v[2]);
01274 }
01275
01276
01277
01278 template <typename Instance, typename SourceContainer, int inlined_capacity>
01279 void InstanceRangedConstructorTestForContainer() {
01280 InstanceTracker tracker;
01281 SourceContainer source_v = {Instance(0), Instance(1)};
01282 tracker.ResetCopiesMovesSwaps();
01283 absl::InlinedVector<Instance, inlined_capacity> v(source_v.begin(),
01284 source_v.end());
01285 EXPECT_EQ(2, v.size());
01286 EXPECT_LT(1, v.capacity());
01287 EXPECT_EQ(0, v[0].value());
01288 EXPECT_EQ(1, v[1].value());
01289 EXPECT_EQ(tracker.copies(), 2);
01290 EXPECT_EQ(tracker.moves(), 0);
01291 }
01292
01293 template <typename Instance, int inlined_capacity>
01294 void InstanceRangedConstructorTestWithCapacity() {
01295
01296
01297 {
01298 SCOPED_TRACE("std::list");
01299 InstanceRangedConstructorTestForContainer<Instance, std::list<Instance>,
01300 inlined_capacity>();
01301 {
01302 SCOPED_TRACE("const std::list");
01303 InstanceRangedConstructorTestForContainer<
01304 Instance, const std::list<Instance>, inlined_capacity>();
01305 }
01306 {
01307 SCOPED_TRACE("std::vector");
01308 InstanceRangedConstructorTestForContainer<Instance, std::vector<Instance>,
01309 inlined_capacity>();
01310 }
01311 {
01312 SCOPED_TRACE("const std::vector");
01313 InstanceRangedConstructorTestForContainer<
01314 Instance, const std::vector<Instance>, inlined_capacity>();
01315 }
01316 }
01317 }
01318
01319 TYPED_TEST_P(InstanceTest, RangedConstructor) {
01320 using Instance = TypeParam;
01321 SCOPED_TRACE("capacity=1");
01322 InstanceRangedConstructorTestWithCapacity<Instance, 1>();
01323 SCOPED_TRACE("capacity=2");
01324 InstanceRangedConstructorTestWithCapacity<Instance, 2>();
01325 }
01326
01327 TEST(RangedConstructor, ElementsAreConstructed) {
01328 std::vector<std::string> source_v = {"cat", "dog"};
01329
01330
01331
01332 absl::InlinedVector<std::string, 1> v(source_v.begin(), source_v.end());
01333 EXPECT_EQ("cat", v[0]);
01334 EXPECT_EQ("dog", v[1]);
01335 }
01336
01337 TEST(RangedAssign, SimpleType) {
01338
01339
01340 for (size_t original_size = 0; original_size <= 5; ++original_size) {
01341 SCOPED_TRACE(original_size);
01342
01343 std::vector<int> original_contents(original_size, 12345);
01344
01345 for (size_t target_size = 0; target_size <= 5; ++target_size) {
01346 SCOPED_TRACE(target_size);
01347
01348
01349 std::vector<int> new_contents;
01350 for (size_t i = 0; i < target_size; ++i) {
01351 new_contents.push_back(i + 3);
01352 }
01353
01354 absl::InlinedVector<int, 3> v(original_contents.begin(),
01355 original_contents.end());
01356 v.assign(new_contents.begin(), new_contents.end());
01357
01358 EXPECT_EQ(new_contents.size(), v.size());
01359 EXPECT_LE(new_contents.size(), v.capacity());
01360 if (target_size <= 3 && original_size <= 3) {
01361
01362 EXPECT_EQ(3, v.capacity());
01363 }
01364 EXPECT_THAT(v, ElementsAreArray(new_contents));
01365 }
01366 }
01367 }
01368
01369
01370 template <typename Instance>
01371 static bool InstanceValuesEqual(const Instance& lhs, const Instance& rhs) {
01372 return lhs.value() == rhs.value();
01373 }
01374
01375
01376
01377 template <typename Instance, typename SourceContainer>
01378 void InstanceRangedAssignTestForContainer() {
01379
01380
01381 for (size_t original_size = 0; original_size <= 5; ++original_size) {
01382 SCOPED_TRACE(original_size);
01383
01384 std::vector<Instance> original_contents(original_size, Instance(12345));
01385
01386 for (size_t target_size = 0; target_size <= 5; ++target_size) {
01387 SCOPED_TRACE(target_size);
01388
01389
01390
01391
01392
01393 std::vector<Instance> new_contents_in;
01394 for (size_t i = 0; i < target_size; ++i) {
01395 new_contents_in.push_back(Instance(i + 3));
01396 }
01397 SourceContainer new_contents(new_contents_in.begin(),
01398 new_contents_in.end());
01399
01400 absl::InlinedVector<Instance, 3> v(original_contents.begin(),
01401 original_contents.end());
01402 v.assign(new_contents.begin(), new_contents.end());
01403
01404 EXPECT_EQ(new_contents.size(), v.size());
01405 EXPECT_LE(new_contents.size(), v.capacity());
01406 if (target_size <= 3 && original_size <= 3) {
01407
01408 EXPECT_EQ(3, v.capacity());
01409 }
01410 EXPECT_TRUE(std::equal(v.begin(), v.end(), new_contents.begin(),
01411 InstanceValuesEqual<Instance>));
01412 }
01413 }
01414 }
01415
01416 TYPED_TEST_P(InstanceTest, RangedAssign) {
01417 using Instance = TypeParam;
01418
01419
01420 SCOPED_TRACE("std::list");
01421 InstanceRangedAssignTestForContainer<Instance, std::list<Instance>>();
01422 SCOPED_TRACE("const std::list");
01423 InstanceRangedAssignTestForContainer<Instance, const std::list<Instance>>();
01424 SCOPED_TRACE("std::vector");
01425 InstanceRangedAssignTestForContainer<Instance, std::vector<Instance>>();
01426 SCOPED_TRACE("const std::vector");
01427 InstanceRangedAssignTestForContainer<Instance, const std::vector<Instance>>();
01428 }
01429
01430 TEST(InitializerListConstructor, SimpleTypeWithInlineBacking) {
01431 EXPECT_THAT((absl::InlinedVector<int, 4>{4, 5, 6}),
01432 AllOf(SizeIs(3), CapacityIs(4), ElementsAre(4, 5, 6)));
01433 }
01434
01435 TEST(InitializerListConstructor, SimpleTypeWithReallocationRequired) {
01436 EXPECT_THAT((absl::InlinedVector<int, 2>{4, 5, 6}),
01437 AllOf(SizeIs(3), CapacityIs(Gt(2)), ElementsAre(4, 5, 6)));
01438 }
01439
01440 TEST(InitializerListConstructor, DisparateTypesInList) {
01441 EXPECT_THAT((absl::InlinedVector<int, 2>{-7, 8ULL}), ElementsAre(-7, 8));
01442
01443 EXPECT_THAT((absl::InlinedVector<std::string, 2>{"foo", std::string("bar")}),
01444 ElementsAre("foo", "bar"));
01445 }
01446
01447 TEST(InitializerListConstructor, ComplexTypeWithInlineBacking) {
01448 EXPECT_THAT((absl::InlinedVector<CopyableMovableInstance, 1>{
01449 CopyableMovableInstance(0)}),
01450 AllOf(SizeIs(1), CapacityIs(1), ElementsAre(ValueIs(0))));
01451 }
01452
01453 TEST(InitializerListConstructor, ComplexTypeWithReallocationRequired) {
01454 EXPECT_THAT(
01455 (absl::InlinedVector<CopyableMovableInstance, 1>{
01456 CopyableMovableInstance(0), CopyableMovableInstance(1)}),
01457 AllOf(SizeIs(2), CapacityIs(Gt(1)), ElementsAre(ValueIs(0), ValueIs(1))));
01458 }
01459
01460 TEST(InitializerListAssign, SimpleTypeFitsInlineBacking) {
01461 for (size_t original_size = 0; original_size <= 4; ++original_size) {
01462 SCOPED_TRACE(original_size);
01463
01464 absl::InlinedVector<int, 2> v1(original_size, 12345);
01465 const size_t original_capacity_v1 = v1.capacity();
01466 v1.assign({3});
01467 EXPECT_THAT(
01468 v1, AllOf(SizeIs(1), CapacityIs(original_capacity_v1), ElementsAre(3)));
01469
01470 absl::InlinedVector<int, 2> v2(original_size, 12345);
01471 const size_t original_capacity_v2 = v2.capacity();
01472 v2 = {3};
01473 EXPECT_THAT(
01474 v2, AllOf(SizeIs(1), CapacityIs(original_capacity_v2), ElementsAre(3)));
01475 }
01476 }
01477
01478 TEST(InitializerListAssign, SimpleTypeDoesNotFitInlineBacking) {
01479 for (size_t original_size = 0; original_size <= 4; ++original_size) {
01480 SCOPED_TRACE(original_size);
01481 absl::InlinedVector<int, 2> v1(original_size, 12345);
01482 v1.assign({3, 4, 5});
01483 EXPECT_THAT(v1, AllOf(SizeIs(3), ElementsAre(3, 4, 5)));
01484 EXPECT_LE(3, v1.capacity());
01485
01486 absl::InlinedVector<int, 2> v2(original_size, 12345);
01487 v2 = {3, 4, 5};
01488 EXPECT_THAT(v2, AllOf(SizeIs(3), ElementsAre(3, 4, 5)));
01489 EXPECT_LE(3, v2.capacity());
01490 }
01491 }
01492
01493 TEST(InitializerListAssign, DisparateTypesInList) {
01494 absl::InlinedVector<int, 2> v_int1;
01495 v_int1.assign({-7, 8ULL});
01496 EXPECT_THAT(v_int1, ElementsAre(-7, 8));
01497
01498 absl::InlinedVector<int, 2> v_int2;
01499 v_int2 = {-7, 8ULL};
01500 EXPECT_THAT(v_int2, ElementsAre(-7, 8));
01501
01502 absl::InlinedVector<std::string, 2> v_string1;
01503 v_string1.assign({"foo", std::string("bar")});
01504 EXPECT_THAT(v_string1, ElementsAre("foo", "bar"));
01505
01506 absl::InlinedVector<std::string, 2> v_string2;
01507 v_string2 = {"foo", std::string("bar")};
01508 EXPECT_THAT(v_string2, ElementsAre("foo", "bar"));
01509 }
01510
01511 TYPED_TEST_P(InstanceTest, InitializerListAssign) {
01512 using Instance = TypeParam;
01513 for (size_t original_size = 0; original_size <= 4; ++original_size) {
01514 SCOPED_TRACE(original_size);
01515 absl::InlinedVector<Instance, 2> v(original_size, Instance(12345));
01516 const size_t original_capacity = v.capacity();
01517 v.assign({Instance(3)});
01518 EXPECT_THAT(v, AllOf(SizeIs(1), CapacityIs(original_capacity),
01519 ElementsAre(ValueIs(3))));
01520 }
01521 for (size_t original_size = 0; original_size <= 4; ++original_size) {
01522 SCOPED_TRACE(original_size);
01523 absl::InlinedVector<Instance, 2> v(original_size, Instance(12345));
01524 v.assign({Instance(3), Instance(4), Instance(5)});
01525 EXPECT_THAT(v, AllOf(SizeIs(3),
01526 ElementsAre(ValueIs(3), ValueIs(4), ValueIs(5))));
01527 EXPECT_LE(3, v.capacity());
01528 }
01529 }
01530
01531 REGISTER_TYPED_TEST_CASE_P(InstanceTest, Swap, CountConstructorsDestructors,
01532 CountConstructorsDestructorsOnCopyConstruction,
01533 CountConstructorsDestructorsOnMoveConstruction,
01534 CountConstructorsDestructorsOnAssignment,
01535 CountConstructorsDestructorsOnMoveAssignment,
01536 CountElemAssignInlineBacking, RangedConstructor,
01537 RangedAssign, InitializerListAssign);
01538
01539 using InstanceTypes =
01540 ::testing::Types<CopyableOnlyInstance, CopyableMovableInstance>;
01541 INSTANTIATE_TYPED_TEST_CASE_P(InstanceTestOnTypes, InstanceTest, InstanceTypes);
01542
01543 TEST(DynamicVec, DynamicVecCompiles) {
01544 DynamicVec v;
01545 (void)v;
01546 }
01547
01548 TEST(AllocatorSupportTest, Constructors) {
01549 using MyAlloc = CountingAllocator<int>;
01550 using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
01551 const int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
01552 int64_t allocated = 0;
01553 MyAlloc alloc(&allocated);
01554 { AllocVec ABSL_ATTRIBUTE_UNUSED v; }
01555 { AllocVec ABSL_ATTRIBUTE_UNUSED v(alloc); }
01556 { AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc); }
01557 { AllocVec ABSL_ATTRIBUTE_UNUSED v({1, 2, 3}, alloc); }
01558
01559 AllocVec v2;
01560 { AllocVec ABSL_ATTRIBUTE_UNUSED v(v2, alloc); }
01561 { AllocVec ABSL_ATTRIBUTE_UNUSED v(std::move(v2), alloc); }
01562 }
01563
01564 TEST(AllocatorSupportTest, CountAllocations) {
01565 using MyAlloc = CountingAllocator<int>;
01566 using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
01567 const int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
01568 int64_t allocated = 0;
01569 MyAlloc alloc(&allocated);
01570 {
01571 AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + 4, alloc);
01572 EXPECT_THAT(allocated, 0);
01573 }
01574 EXPECT_THAT(allocated, 0);
01575 {
01576 AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc);
01577 EXPECT_THAT(allocated, v.size() * sizeof(int));
01578 }
01579 EXPECT_THAT(allocated, 0);
01580 {
01581 AllocVec v(4, 1, alloc);
01582 EXPECT_THAT(allocated, 0);
01583
01584 int64_t allocated2 = 0;
01585 MyAlloc alloc2(&allocated2);
01586 AllocVec v2(v, alloc2);
01587 EXPECT_THAT(allocated2, 0);
01588
01589 int64_t allocated3 = 0;
01590 MyAlloc alloc3(&allocated3);
01591 AllocVec v3(std::move(v), alloc3);
01592 EXPECT_THAT(allocated3, 0);
01593 }
01594 EXPECT_THAT(allocated, 0);
01595 {
01596 AllocVec v(8, 2, alloc);
01597 EXPECT_THAT(allocated, v.size() * sizeof(int));
01598
01599 int64_t allocated2 = 0;
01600 MyAlloc alloc2(&allocated2);
01601 AllocVec v2(v, alloc2);
01602 EXPECT_THAT(allocated2, v2.size() * sizeof(int));
01603
01604 int64_t allocated3 = 0;
01605 MyAlloc alloc3(&allocated3);
01606 AllocVec v3(std::move(v), alloc3);
01607 EXPECT_THAT(allocated3, v3.size() * sizeof(int));
01608 }
01609 EXPECT_EQ(allocated, 0);
01610 {
01611
01612 AllocVec v(8, 2, alloc);
01613 EXPECT_EQ(allocated, 8 * sizeof(int));
01614 v.resize(5);
01615 EXPECT_EQ(allocated, 8 * sizeof(int));
01616 v.shrink_to_fit();
01617 EXPECT_EQ(allocated, 5 * sizeof(int));
01618 v.resize(4);
01619 EXPECT_EQ(allocated, 5 * sizeof(int));
01620 v.shrink_to_fit();
01621 EXPECT_EQ(allocated, 0);
01622 }
01623 }
01624
01625 TEST(AllocatorSupportTest, SwapBothAllocated) {
01626 using MyAlloc = CountingAllocator<int>;
01627 using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
01628 int64_t allocated1 = 0;
01629 int64_t allocated2 = 0;
01630 {
01631 const int ia1[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
01632 const int ia2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
01633 MyAlloc a1(&allocated1);
01634 MyAlloc a2(&allocated2);
01635 AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1);
01636 AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2);
01637 EXPECT_LT(v1.capacity(), v2.capacity());
01638 EXPECT_THAT(allocated1, v1.capacity() * sizeof(int));
01639 EXPECT_THAT(allocated2, v2.capacity() * sizeof(int));
01640 v1.swap(v2);
01641 EXPECT_THAT(v1, ElementsAreArray(ia2));
01642 EXPECT_THAT(v2, ElementsAreArray(ia1));
01643 EXPECT_THAT(allocated1, v2.capacity() * sizeof(int));
01644 EXPECT_THAT(allocated2, v1.capacity() * sizeof(int));
01645 }
01646 EXPECT_THAT(allocated1, 0);
01647 EXPECT_THAT(allocated2, 0);
01648 }
01649
01650 TEST(AllocatorSupportTest, SwapOneAllocated) {
01651 using MyAlloc = CountingAllocator<int>;
01652 using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
01653 int64_t allocated1 = 0;
01654 int64_t allocated2 = 0;
01655 {
01656 const int ia1[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
01657 const int ia2[] = { 0, 1, 2, 3 };
01658 MyAlloc a1(&allocated1);
01659 MyAlloc a2(&allocated2);
01660 AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1);
01661 AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2);
01662 EXPECT_THAT(allocated1, v1.capacity() * sizeof(int));
01663 EXPECT_THAT(allocated2, 0);
01664 v1.swap(v2);
01665 EXPECT_THAT(v1, ElementsAreArray(ia2));
01666 EXPECT_THAT(v2, ElementsAreArray(ia1));
01667 EXPECT_THAT(allocated1, v2.capacity() * sizeof(int));
01668 EXPECT_THAT(allocated2, 0);
01669 EXPECT_TRUE(v2.get_allocator() == a1);
01670 EXPECT_TRUE(v1.get_allocator() == a2);
01671 }
01672 EXPECT_THAT(allocated1, 0);
01673 EXPECT_THAT(allocated2, 0);
01674 }
01675
01676 TEST(AllocatorSupportTest, ScopedAllocatorWorks) {
01677 using StdVector = std::vector<int, CountingAllocator<int>>;
01678 using MyAlloc =
01679 std::scoped_allocator_adaptor<CountingAllocator<StdVector>>;
01680 using AllocVec = absl::InlinedVector<StdVector, 4, MyAlloc>;
01681
01682
01683
01684 int64_t test_allocated = 0;
01685 StdVector v(CountingAllocator<int>{&test_allocated});
01686
01687 auto default_std_vec_allocated = test_allocated;
01688 v.push_back(1);
01689
01690
01691 int64_t one_element_std_vec_copy_allocated = test_allocated;
01692
01693 int64_t allocated = 0;
01694 AllocVec vec(MyAlloc{CountingAllocator<StdVector>{&allocated}});
01695 EXPECT_EQ(allocated, 0);
01696
01697
01698
01699
01700
01701 auto expected = default_std_vec_allocated;
01702 vec.resize(1);
01703 EXPECT_EQ(allocated, expected);
01704
01705
01706
01707
01708
01709 expected += sizeof(int);
01710 vec[0].push_back(1);
01711 EXPECT_EQ(allocated, expected);
01712
01713
01714 expected += one_element_std_vec_copy_allocated;
01715 vec.push_back(vec[0]);
01716 EXPECT_EQ(allocated, expected);
01717
01718
01719
01720 expected += sizeof(StdVector) * 8 + default_std_vec_allocated * 3;
01721 vec.resize(5);
01722 EXPECT_EQ(allocated, expected);
01723
01724
01725 expected += one_element_std_vec_copy_allocated;
01726 vec.push_back(vec[0]);
01727 EXPECT_EQ(allocated, expected);
01728
01729
01730
01731 expected += sizeof(int);
01732 vec[0].push_back(1);
01733 EXPECT_EQ(allocated, expected);
01734
01735 vec.clear();
01736 EXPECT_EQ(allocated, 0);
01737 }
01738
01739 TEST(AllocatorSupportTest, SizeAllocConstructor) {
01740 constexpr int inlined_size = 4;
01741 using Alloc = CountingAllocator<int>;
01742 using AllocVec = absl::InlinedVector<int, inlined_size, Alloc>;
01743
01744 {
01745 auto len = inlined_size / 2;
01746 int64_t allocated = 0;
01747 auto v = AllocVec(len, Alloc(&allocated));
01748
01749
01750 EXPECT_THAT(allocated, 0);
01751 EXPECT_THAT(v, AllOf(SizeIs(len), Each(0)));
01752 }
01753
01754 {
01755 auto len = inlined_size * 2;
01756 int64_t allocated = 0;
01757 auto v = AllocVec(len, Alloc(&allocated));
01758
01759
01760 EXPECT_THAT(allocated, len * sizeof(int));
01761 EXPECT_THAT(v, AllOf(SizeIs(len), Each(0)));
01762 }
01763 }
01764
01765 TEST(InlinedVectorTest, AbslHashValueWorks) {
01766 using V = absl::InlinedVector<int, 4>;
01767 std::vector<V> cases;
01768
01769
01770
01771 for (int i = 0; i < 10; ++i) {
01772 V v;
01773 for (int j = 0; j < i; ++j) {
01774 v.push_back(j);
01775 }
01776 cases.push_back(v);
01777 v.resize(i % 4);
01778 cases.push_back(v);
01779 }
01780
01781 EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(cases));
01782 }
01783
01784 }