18 #include <forward_list> 21 #include <scoped_allocator> 27 #include "gmock/gmock.h" 28 #include "gtest/gtest.h" 47 using testing::ElementsAre;
48 using testing::ElementsAreArray;
51 using testing::PrintToString;
55 MATCHER_P(SizeIs,
n,
"") {
56 return testing::ExplainMatchResult(
n,
arg.size(), result_listener);
59 MATCHER_P(CapacityIs,
n,
"") {
60 return testing::ExplainMatchResult(
n,
arg.capacity(), result_listener);
63 MATCHER_P(ValueIs, e,
"") {
64 return testing::ExplainMatchResult(e,
arg.value(), result_listener);
72 class InstanceTest :
public ::testing::Test {};
79 RefCounted(
int value,
int* count) : value_(value), count_(count) {
83 RefCounted(
const RefCounted&
v)
84 : value_(v.value_), count_(v.count_) {
93 friend void swap(RefCounted&
a, RefCounted&
b) {
95 swap(a.value_, b.value_);
96 swap(a.count_, b.count_);
99 RefCounted& operator=(RefCounted
v) {
124 virtual ~Dynamic() {}
130 template <
typename Container>
131 static void Fill(Container*
v,
int len,
int offset = 0) {
132 for (
int i = 0;
i <
len;
i++) {
137 static IntVec Fill(
int len,
int offset = 0) {
139 Fill(&v, len, offset);
143 TEST(IntVec, SimpleOps) {
144 for (
int len = 0; len < 20; len++) {
146 const IntVec& cv =
v;
149 EXPECT_EQ(len, v.size());
150 EXPECT_LE(len, v.capacity());
152 for (
int i = 0;
i <
len;
i++) {
154 EXPECT_EQ(
i, v.at(
i));
156 EXPECT_EQ(v.begin(), v.data());
157 EXPECT_EQ(cv.begin(), cv.data());
160 for (IntVec::iterator iter = v.begin(); iter != v.end(); ++iter) {
161 EXPECT_EQ(counter, *iter);
164 EXPECT_EQ(counter, len);
167 for (IntVec::const_iterator iter = v.begin(); iter != v.end(); ++iter) {
168 EXPECT_EQ(counter, *iter);
171 EXPECT_EQ(counter, len);
174 for (IntVec::const_iterator iter = v.cbegin(); iter != v.cend(); ++iter) {
175 EXPECT_EQ(counter, *iter);
178 EXPECT_EQ(counter, len);
181 EXPECT_EQ(0, v.front());
182 EXPECT_EQ(len - 1, v.back());
184 EXPECT_EQ(len - 1, v.size());
185 for (
int i = 0;
i < v.size(); ++
i) {
187 EXPECT_EQ(
i, v.at(
i));
193 TEST(IntVec, AtThrows) {
194 IntVec v = {1, 2, 3};
195 EXPECT_EQ(v.at(2), 3);
197 "failed bounds check");
200 TEST(IntVec, ReverseIterator) {
201 for (
int len = 0; len < 20; len++) {
206 for (IntVec::reverse_iterator iter = v.rbegin(); iter != v.rend(); ++iter) {
208 EXPECT_EQ(counter, *iter);
210 EXPECT_EQ(counter, 0);
213 for (IntVec::const_reverse_iterator iter = v.rbegin(); iter != v.rend();
216 EXPECT_EQ(counter, *iter);
218 EXPECT_EQ(counter, 0);
221 for (IntVec::const_reverse_iterator iter = v.crbegin(); iter != v.crend();
224 EXPECT_EQ(counter, *iter);
226 EXPECT_EQ(counter, 0);
230 TEST(IntVec, Erase) {
231 for (
int len = 1; len < 20; len++) {
232 for (
int i = 0;
i <
len; ++
i) {
235 v.erase(v.begin() +
i);
236 EXPECT_EQ(len - 1, v.size());
237 for (
int j = 0; j <
i; ++j) {
240 for (
int j = i; j < len - 1; ++j) {
241 EXPECT_EQ(j + 1, v[j]);
250 TEST(RefCountedVec, EraseBeginEnd) {
251 for (
int len = 1; len < 20; ++
len) {
252 for (
int erase_begin = 0; erase_begin <
len; ++erase_begin) {
253 for (
int erase_end = erase_begin; erase_end <=
len; ++erase_end) {
254 std::vector<int> counts(len, 0);
256 for (
int i = 0;
i <
len; ++
i) {
257 v.push_back(RefCounted(
i, &counts[
i]));
260 int erase_len = erase_end - erase_begin;
262 v.erase(v.begin() + erase_begin, v.begin() + erase_end);
264 EXPECT_EQ(len - erase_len, v.size());
267 for (
int i = 0;
i < erase_begin; ++
i) {
268 EXPECT_EQ(
i, v[
i].value_);
272 for (
int i = erase_begin;
i < v.size(); ++
i) {
273 EXPECT_EQ(
i + erase_len, v[
i].value_);
277 for (
int i = 0;
i < erase_begin; ++
i) {
278 EXPECT_EQ(1, counts[
i]);
282 for (
int i = erase_begin;
i < erase_end; ++
i) {
283 EXPECT_EQ(0, counts[
i]);
287 for (
int i = erase_end;
i<
len; ++
i) {
288 EXPECT_EQ(1, counts[
i]);
295 struct NoDefaultCtor {
296 explicit NoDefaultCtor(
int) {}
300 NoCopy(
const NoCopy&) =
delete;
304 NoAssign& operator=(
const NoAssign&) =
delete;
308 MoveOnly(MoveOnly&&) =
default;
309 MoveOnly& operator=(MoveOnly&&) =
default;
311 TEST(InlinedVectorTest, NoDefaultCtor) {
315 TEST(InlinedVectorTest, NoCopy) {
319 TEST(InlinedVectorTest, NoAssign) {
323 TEST(InlinedVectorTest, MoveOnly) {
335 TEST(InlinedVectorTest, Noexcept) {
337 EXPECT_TRUE((std::is_nothrow_move_constructible<
340 struct MoveCanThrow {
341 MoveCanThrow(MoveCanThrow&&) {}
344 (std::is_nothrow_move_constructible<
348 TEST(InlinedVectorTest, EmplaceBack) {
352 EXPECT_EQ(&inlined_element, &v[0]);
353 EXPECT_EQ(inlined_element.first,
"answer");
354 EXPECT_EQ(inlined_element.second, 42);
356 auto& allocated_element = v.
emplace_back(
"taxicab", 1729);
357 EXPECT_EQ(&allocated_element, &v[1]);
358 EXPECT_EQ(allocated_element.first,
"taxicab");
359 EXPECT_EQ(allocated_element.second, 1729);
362 TEST(InlinedVectorTest, ShrinkToFitGrowingVector) {
383 TEST(InlinedVectorTest, ShrinkToFitEdgeCases) {
392 EXPECT_EQ(v[0].first,
"answer");
393 EXPECT_EQ(v[0].second, 42);
425 TEST(IntVec, Insert) {
426 for (
int len = 0; len < 20; len++) {
427 for (
int pos = 0; pos <=
len; pos++) {
430 std::vector<int> std_v;
435 std_v.insert(std_v.begin() + pos, 9999);
436 IntVec::iterator it = v.insert(v.cbegin() + pos, 9999);
437 EXPECT_THAT(v, ElementsAreArray(std_v));
438 EXPECT_EQ(it, v.cbegin() + pos);
442 std::vector<int> std_v;
447 IntVec::size_type
n = 5;
448 std_v.insert(std_v.begin() + pos,
n, 9999);
449 IntVec::iterator it = v.insert(v.cbegin() + pos,
n, 9999);
450 EXPECT_THAT(v, ElementsAreArray(std_v));
451 EXPECT_EQ(it, v.cbegin() + pos);
455 std::vector<int> std_v;
460 const std::vector<int> input = {9999, 8888, 7777};
461 std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend());
462 IntVec::iterator it =
463 v.insert(v.cbegin() + pos, input.cbegin(), input.cend());
464 EXPECT_THAT(v, ElementsAreArray(std_v));
465 EXPECT_EQ(it, v.cbegin() + pos);
469 std::vector<int> std_v;
474 const std::forward_list<int> input = {9999, 8888, 7777};
475 std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend());
476 IntVec::iterator it =
477 v.insert(v.cbegin() + pos, input.cbegin(), input.cend());
478 EXPECT_THAT(v, ElementsAreArray(std_v));
479 EXPECT_EQ(it, v.cbegin() + pos);
483 std::vector<int> std_v;
488 std_v.insert(std_v.begin() + pos, {9999, 8888, 7777});
489 std::istringstream input(
"9999 8888 7777");
490 IntVec::iterator it =
491 v.insert(v.cbegin() + pos, std::istream_iterator<int>(input),
492 std::istream_iterator<int>());
493 EXPECT_THAT(v, ElementsAreArray(std_v));
494 EXPECT_EQ(it, v.cbegin() + pos);
498 std::vector<int> std_v;
503 std_v.insert(std_v.begin() + pos, {9999, 8888});
504 IntVec::iterator it = v.insert(v.cbegin() + pos, {9999, 8888});
505 EXPECT_THAT(v, ElementsAreArray(std_v));
506 EXPECT_EQ(it, v.cbegin() + pos);
512 TEST(RefCountedVec, InsertConstructorDestructor) {
515 for (
int len = 0; len < 20; len++) {
517 for (
int pos = 0; pos <=
len; pos++) {
519 std::vector<int> counts(len, 0);
520 int inserted_count = 0;
522 for (
int i = 0;
i <
len; ++
i) {
524 v.push_back(RefCounted(
i, &counts[
i]));
527 EXPECT_THAT(counts, Each(Eq(1)));
529 RefCounted insert_element(9999, &inserted_count);
530 EXPECT_EQ(1, inserted_count);
531 v.insert(v.begin() + pos, insert_element);
532 EXPECT_EQ(2, inserted_count);
534 EXPECT_THAT(counts, Each(Eq(1)));
535 EXPECT_EQ(2, inserted_count);
540 TEST(IntVec, Resize) {
541 for (
int len = 0; len < 20; len++) {
546 static const int kResizeElem = 1000000;
547 for (
int k = 0; k < 10; k++) {
549 v.resize(len+k, kResizeElem);
550 EXPECT_EQ(len+k, v.size());
551 EXPECT_LE(len+k, v.capacity());
552 for (
int i = 0;
i < len+k;
i++) {
556 EXPECT_EQ(kResizeElem, v[
i]);
561 v.resize(len, kResizeElem);
562 EXPECT_EQ(len, v.size());
563 EXPECT_LE(len, v.capacity());
564 for (
int i = 0;
i <
len;
i++) {
571 TEST(IntVec, InitWithLength) {
572 for (
int len = 0; len < 20; len++) {
574 EXPECT_EQ(len, v.size());
575 EXPECT_LE(len, v.capacity());
576 for (
int i = 0;
i <
len;
i++) {
582 TEST(IntVec, CopyConstructorAndAssignment) {
583 for (
int len = 0; len < 20; len++) {
586 EXPECT_EQ(len, v.size());
587 EXPECT_LE(len, v.capacity());
590 EXPECT_TRUE(v == v2) << PrintToString(v) << PrintToString(v2);
592 for (
int start_len = 0; start_len < 20; start_len++) {
594 Fill(&v3, start_len, 99);
596 EXPECT_TRUE(v == v3) << PrintToString(v) << PrintToString(v3);
601 TEST(IntVec, AliasingCopyAssignment) {
602 for (
int len = 0; len < 20; ++
len) {
604 Fill(&original, len);
605 IntVec dup = original;
607 EXPECT_EQ(dup, original);
611 TEST(IntVec, MoveConstructorAndAssignment) {
612 for (
int len = 0; len < 20; len++) {
614 const int inlined_capacity = v_in.capacity();
616 EXPECT_EQ(len, v_in.size());
617 EXPECT_LE(len, v_in.capacity());
621 auto* old_data = v_temp.data();
623 EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out);
624 if (v_in.size() > inlined_capacity) {
626 EXPECT_TRUE(v_out.data() == old_data);
628 EXPECT_FALSE(v_out.data() == old_data);
631 for (
int start_len = 0; start_len < 20; start_len++) {
633 Fill(&v_out, start_len, 99);
635 auto* old_data = v_temp.data();
637 EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out);
638 if (v_in.size() > inlined_capacity) {
640 EXPECT_TRUE(v_out.data() == old_data);
642 EXPECT_FALSE(v_out.data() == old_data);
648 class NotTriviallyDestructible {
650 NotTriviallyDestructible() :
p_(new int(1)) {}
651 explicit NotTriviallyDestructible(
int i) :
p_(new int(i)) {}
653 NotTriviallyDestructible(
const NotTriviallyDestructible& other)
654 :
p_(new int(*other.
p_)) {}
656 NotTriviallyDestructible& operator=(
const NotTriviallyDestructible& other) {
657 p_ = absl::make_unique<int>(*other.p_);
661 bool operator==(
const NotTriviallyDestructible& other)
const {
662 return *
p_ == *other.p_;
666 std::unique_ptr<int>
p_;
669 TEST(AliasingTest, Emplace) {
670 for (
int i = 2;
i < 20; ++
i) {
672 for (
int j = 0; j <
i; ++j) {
673 vec.
push_back(NotTriviallyDestructible(j));
676 EXPECT_EQ(vec[0], vec[1]);
678 EXPECT_EQ(vec[i / 2], vec[i / 2 + 1]);
680 EXPECT_EQ(vec[vec.
size() - 2], vec.
back());
684 TEST(AliasingTest, InsertWithCount) {
685 for (
int i = 1; i < 20; ++
i) {
687 for (
int j = 0; j <
i; ++j) {
688 vec.
push_back(NotTriviallyDestructible(j));
690 for (
int n = 0; n < 5; ++
n) {
695 std::all_of(
b,
b + n, [&vec](
const NotTriviallyDestructible& x) {
696 return x == vec.
back();
699 auto m_idx = vec.
size() / 2;
701 auto m = vec.
begin() + m_idx;
703 std::all_of(m, m + n, [&vec](
const NotTriviallyDestructible& x) {
704 return x == vec.
back();
709 auto old_e = vec.
size() - 1;
710 auto val = vec[old_e];
712 auto e = vec.
begin() + old_e;
713 EXPECT_TRUE(std::all_of(
715 [&val](
const NotTriviallyDestructible& x) {
return x == val; }));
720 TEST(OverheadTest, Storage) {
725 EXPECT_EQ(2 *
sizeof(
int*),
727 EXPECT_EQ(1 *
sizeof(
int*),
729 EXPECT_EQ(1 *
sizeof(
int*),
731 EXPECT_EQ(1 *
sizeof(
int*),
733 EXPECT_EQ(1 *
sizeof(
int*),
735 EXPECT_EQ(1 *
sizeof(
int*),
737 EXPECT_EQ(1 *
sizeof(
int*),
739 EXPECT_EQ(1 *
sizeof(
int*),
743 TEST(IntVec, Clear) {
744 for (
int len = 0; len < 20; len++) {
749 EXPECT_EQ(0, v.size());
750 EXPECT_EQ(v.begin(), v.end());
754 TEST(IntVec, Reserve) {
755 for (
int len = 0; len < 20; len++) {
759 for (
int newlen = 0; newlen < 100; newlen++) {
760 const int* start_rep = v.data();
762 const int* final_rep = v.data();
764 EXPECT_EQ(start_rep, final_rep);
766 EXPECT_LE(newlen, v.capacity());
769 while (v.size() < newlen) {
772 EXPECT_EQ(final_rep, v.data());
777 TEST(StringVec, SelfRefPushBack) {
778 std::vector<std::string> std_v;
780 const std::string s =
"A quite long std::string to ensure heap.";
783 for (
int i = 0; i < 20; ++
i) {
784 EXPECT_THAT(v, ElementsAreArray(std_v));
787 std_v.push_back(std_v.back());
789 EXPECT_THAT(v, ElementsAreArray(std_v));
792 TEST(StringVec, SelfRefPushBackWithMove) {
793 std::vector<std::string> std_v;
795 const std::string s =
"A quite long std::string to ensure heap.";
798 for (
int i = 0; i < 20; ++
i) {
799 EXPECT_EQ(v.
back(), std_v.back());
802 std_v.push_back(
std::move(std_v.back()));
804 EXPECT_EQ(v.
back(), std_v.back());
807 TEST(StringVec, SelfMove) {
808 const std::string s =
"A quite long std::string to ensure heap.";
809 for (
int len = 0; len < 20; len++) {
812 for (
int i = 0; i <
len; ++
i) {
821 std::vector<std::string> copy(v.
begin(), v.
end());
826 for (
int l1 = 0; l1 < 20; l1++) {
828 for (
int l2 = 0; l2 < 20; l2++) {
830 IntVec
a = Fill(l1, 0);
831 IntVec
b = Fill(l2, 100);
836 EXPECT_EQ(l1, b.size());
837 EXPECT_EQ(l2, a.size());
838 for (
int i = 0; i < l1; i++) {
842 for (
int i = 0; i < l2; i++) {
844 EXPECT_EQ(100 + i, a[i]);
851 using Instance = TypeParam;
853 for (
int l1 = 0; l1 < 20; l1++) {
855 for (
int l2 = 0; l2 < 20; l2++) {
859 const size_t inlined_capacity = a.capacity();
860 auto min_len = std::min(l1, l2);
861 auto max_len = std::max(l1, l2);
862 for (
int i = 0; i < l1; i++) a.push_back(Instance(i));
863 for (
int i = 0; i < l2; i++) b.push_back(Instance(100+i));
864 EXPECT_EQ(tracker.instances(), l1 + l2);
865 tracker.ResetCopiesMovesSwaps();
870 EXPECT_EQ(tracker.instances(), l1 + l2);
871 if (a.size() > inlined_capacity && b.size() > inlined_capacity) {
872 EXPECT_EQ(tracker.swaps(), 0);
873 EXPECT_EQ(tracker.moves(), 0);
874 }
else if (a.size() <= inlined_capacity && b.size() <= inlined_capacity) {
875 EXPECT_EQ(tracker.swaps(), min_len);
876 EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()),
881 EXPECT_EQ(tracker.swaps(), 0);
882 EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()),
886 EXPECT_EQ(l1, b.size());
887 EXPECT_EQ(l2, a.size());
888 for (
int i = 0; i < l1; i++) {
889 EXPECT_EQ(i, b[i].
value());
891 for (
int i = 0; i < l2; i++) {
892 EXPECT_EQ(100 + i, a[i].
value());
898 TEST(IntVec, EqualAndNotEqual) {
901 EXPECT_FALSE(a != b);
904 EXPECT_FALSE(a == b);
909 EXPECT_FALSE(a != b);
912 EXPECT_FALSE(a == b);
916 EXPECT_FALSE(a == b);
921 for (
int i = 0; i < 100; i++) {
925 EXPECT_FALSE(a != b);
928 EXPECT_FALSE(a == b);
933 EXPECT_FALSE(a != b);
937 TEST(IntVec, RelationalOps) {
953 EXPECT_FALSE(b <= a);
954 EXPECT_FALSE(a >= b);
958 TYPED_TEST_P(InstanceTest, CountConstructorsDestructors) {
959 using Instance = TypeParam;
962 for (
int len = 0; len < 20; len++) {
964 tracker.ResetCopiesMovesSwaps();
967 const size_t inlined_capacity = v.capacity();
968 for (
int i = 0; i <
len; i++) {
969 v.push_back(Instance(i));
971 EXPECT_EQ(tracker.instances(),
len);
972 EXPECT_GE(tracker.copies() + tracker.moves(),
974 tracker.ResetCopiesMovesSwaps();
977 tracker.ResetCopiesMovesSwaps();
978 v.resize(len + 10, Instance(100));
979 EXPECT_EQ(tracker.instances(), len + 10);
980 if (len <= inlined_capacity && len + 10 > inlined_capacity) {
981 EXPECT_EQ(tracker.copies() + tracker.moves(), 10 +
len);
985 EXPECT_GE(tracker.copies() + tracker.moves(),
990 tracker.ResetCopiesMovesSwaps();
991 v.resize(len, Instance(100));
992 EXPECT_EQ(tracker.instances(),
len);
993 EXPECT_EQ(tracker.copies(), 0);
994 EXPECT_EQ(tracker.moves(), 0);
997 SCOPED_TRACE(
"reserve");
999 EXPECT_EQ(tracker.instances(),
len);
1000 EXPECT_EQ(tracker.copies() + tracker.moves(),
len);
1004 tracker.ResetCopiesMovesSwaps();
1006 EXPECT_EQ(tracker.instances(), len - 1);
1007 EXPECT_EQ(tracker.copies(), 0);
1008 EXPECT_EQ(tracker.moves(), 0);
1011 tracker.ResetCopiesMovesSwaps();
1013 EXPECT_EQ(tracker.instances(), len - 2);
1014 EXPECT_EQ(tracker.copies() + tracker.moves(), len - 2);
1018 tracker.ResetCopiesMovesSwaps();
1019 int instances_before_empty_erase = tracker.instances();
1020 v.erase(v.begin(), v.begin());
1021 EXPECT_EQ(tracker.instances(), instances_before_empty_erase);
1022 EXPECT_EQ(tracker.copies() + tracker.moves(), 0);
1026 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnCopyConstruction) {
1027 using Instance = TypeParam;
1030 for (
int len = 0; len < 20; len++) {
1032 tracker.ResetCopiesMovesSwaps();
1035 for (
int i = 0; i <
len; i++) {
1036 v.push_back(Instance(i));
1038 EXPECT_EQ(tracker.instances(),
len);
1039 EXPECT_GE(tracker.copies() + tracker.moves(),
1041 tracker.ResetCopiesMovesSwaps();
1043 InstanceVec v_copy(v);
1044 EXPECT_EQ(tracker.instances(), len +
len);
1045 EXPECT_EQ(tracker.copies(),
len);
1046 EXPECT_EQ(tracker.moves(), 0);
1048 EXPECT_EQ(tracker.instances(),
len);
1052 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveConstruction) {
1053 using Instance = TypeParam;
1056 for (
int len = 0; len < 20; len++) {
1058 tracker.ResetCopiesMovesSwaps();
1061 const size_t inlined_capacity = v.capacity();
1062 for (
int i = 0; i <
len; i++) {
1063 v.push_back(Instance(i));
1065 EXPECT_EQ(tracker.instances(),
len);
1066 EXPECT_GE(tracker.copies() + tracker.moves(),
1068 tracker.ResetCopiesMovesSwaps();
1071 if (len > inlined_capacity) {
1073 EXPECT_EQ(tracker.instances(),
len);
1074 EXPECT_EQ(tracker.live_instances(),
len);
1076 EXPECT_EQ(v.size(), 0);
1077 EXPECT_EQ(tracker.copies(), 0);
1078 EXPECT_EQ(tracker.moves(), 0);
1080 EXPECT_EQ(tracker.instances(), len +
len);
1081 if (Instance::supports_move()) {
1082 EXPECT_EQ(tracker.live_instances(),
len);
1083 EXPECT_EQ(tracker.copies(), 0);
1084 EXPECT_EQ(tracker.moves(),
len);
1086 EXPECT_EQ(tracker.live_instances(), len +
len);
1087 EXPECT_EQ(tracker.copies(),
len);
1088 EXPECT_EQ(tracker.moves(), 0);
1091 EXPECT_EQ(tracker.swaps(), 0);
1096 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnAssignment) {
1097 using Instance = TypeParam;
1100 for (
int len = 0; len < 20; len++) {
1102 for (
int longorshort = 0; longorshort <= 1; ++longorshort) {
1103 SCOPED_TRACE(longorshort);
1104 tracker.ResetCopiesMovesSwaps();
1106 InstanceVec longer, shorter;
1107 for (
int i = 0; i <
len; i++) {
1108 longer.push_back(Instance(i));
1109 shorter.push_back(Instance(i));
1111 longer.push_back(Instance(len));
1112 EXPECT_EQ(tracker.instances(), len + len + 1);
1113 EXPECT_GE(tracker.copies() + tracker.moves(),
1116 tracker.ResetCopiesMovesSwaps();
1119 EXPECT_EQ(tracker.instances(), (len + 1) + (len + 1));
1120 EXPECT_GE(tracker.copies() + tracker.moves(),
1124 EXPECT_EQ(tracker.instances(), len +
len);
1125 EXPECT_EQ(tracker.copies() + tracker.moves(),
len);
1131 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveAssignment) {
1132 using Instance = TypeParam;
1135 for (
int len = 0; len < 20; len++) {
1137 for (
int longorshort = 0; longorshort <= 1; ++longorshort) {
1138 SCOPED_TRACE(longorshort);
1139 tracker.ResetCopiesMovesSwaps();
1141 InstanceVec longer, shorter;
1142 const int inlined_capacity = longer.capacity();
1143 for (
int i = 0; i <
len; i++) {
1144 longer.push_back(Instance(i));
1145 shorter.push_back(Instance(i));
1147 longer.push_back(Instance(len));
1148 EXPECT_EQ(tracker.instances(), len + len + 1);
1149 EXPECT_GE(tracker.copies() + tracker.moves(),
1152 tracker.ResetCopiesMovesSwaps();
1161 if (src_len > inlined_capacity) {
1163 EXPECT_EQ(tracker.instances(), src_len);
1164 EXPECT_EQ(tracker.live_instances(), src_len);
1165 EXPECT_EQ(tracker.copies(), 0);
1166 EXPECT_EQ(tracker.moves(), 0);
1169 EXPECT_EQ(tracker.instances(), src_len + src_len);
1170 if (Instance::supports_move()) {
1171 EXPECT_EQ(tracker.copies(), 0);
1172 EXPECT_EQ(tracker.moves(), src_len);
1173 EXPECT_EQ(tracker.live_instances(), src_len);
1175 EXPECT_EQ(tracker.copies(), src_len);
1176 EXPECT_EQ(tracker.moves(), 0);
1177 EXPECT_EQ(tracker.live_instances(), src_len + src_len);
1180 EXPECT_EQ(tracker.swaps(), 0);
1185 TEST(CountElemAssign, SimpleTypeWithInlineBacking) {
1186 for (
size_t original_size = 0; original_size <= 5; ++original_size) {
1187 SCOPED_TRACE(original_size);
1189 std::vector<int> original_contents(original_size, 12345);
1192 original_contents.end());
1194 EXPECT_THAT(v,
AllOf(SizeIs(2), ElementsAre(123, 123)));
1195 if (original_size <= 2) {
1197 EXPECT_EQ(2, v.capacity());
1202 TEST(CountElemAssign, SimpleTypeWithAllocation) {
1203 for (
size_t original_size = 0; original_size <= 5; ++original_size) {
1204 SCOPED_TRACE(original_size);
1206 std::vector<int> original_contents(original_size, 12345);
1209 original_contents.end());
1211 EXPECT_THAT(v,
AllOf(SizeIs(3), ElementsAre(123, 123, 123)));
1212 EXPECT_LE(v.size(), v.capacity());
1216 TYPED_TEST_P(InstanceTest, CountElemAssignInlineBacking) {
1217 using Instance = TypeParam;
1218 for (
size_t original_size = 0; original_size <= 5; ++original_size) {
1219 SCOPED_TRACE(original_size);
1221 std::vector<Instance> original_contents(original_size, Instance(12345));
1224 original_contents.end());
1225 v.assign(2, Instance(123));
1226 EXPECT_THAT(v,
AllOf(SizeIs(2), ElementsAre(ValueIs(123), ValueIs(123))));
1227 if (original_size <= 2) {
1229 EXPECT_EQ(2, v.capacity());
1234 template <
typename Instance>
1235 void InstanceCountElemAssignWithAllocationTest() {
1236 for (
size_t original_size = 0; original_size <= 5; ++original_size) {
1237 SCOPED_TRACE(original_size);
1239 std::vector<Instance> original_contents(original_size, Instance(12345));
1242 original_contents.end());
1243 v.assign(3, Instance(123));
1246 ElementsAre(ValueIs(123), ValueIs(123), ValueIs(123))));
1247 EXPECT_LE(v.size(), v.capacity());
1250 TEST(CountElemAssign, WithAllocationCopyableInstance) {
1251 InstanceCountElemAssignWithAllocationTest<CopyableOnlyInstance>();
1253 TEST(CountElemAssign, WithAllocationCopyableMovableInstance) {
1254 InstanceCountElemAssignWithAllocationTest<CopyableMovableInstance>();
1257 TEST(RangedConstructor, SimpleType) {
1258 std::vector<int> source_v = {4, 5, 6};
1261 EXPECT_EQ(3, v.size());
1262 EXPECT_EQ(4, v.capacity());
1269 EXPECT_EQ(3, realloc_v.size());
1270 EXPECT_LT(2, realloc_v.capacity());
1271 EXPECT_EQ(4, realloc_v[0]);
1272 EXPECT_EQ(5, realloc_v[1]);
1273 EXPECT_EQ(6, realloc_v[2]);
1278 template <
typename Instance,
typename SourceContainer,
int inlined_capacity>
1279 void InstanceRangedConstructorTestForContainer() {
1281 SourceContainer source_v = {Instance(0), Instance(1)};
1282 tracker.ResetCopiesMovesSwaps();
1285 EXPECT_EQ(2, v.size());
1286 EXPECT_LT(1, v.capacity());
1287 EXPECT_EQ(0, v[0].
value());
1288 EXPECT_EQ(1, v[1].
value());
1289 EXPECT_EQ(tracker.copies(), 2);
1290 EXPECT_EQ(tracker.moves(), 0);
1293 template <
typename Instance,
int inlined_capacity>
1294 void InstanceRangedConstructorTestWithCapacity() {
1298 SCOPED_TRACE(
"std::list");
1299 InstanceRangedConstructorTestForContainer<Instance, std::list<Instance>,
1300 inlined_capacity>();
1302 SCOPED_TRACE(
"const std::list");
1303 InstanceRangedConstructorTestForContainer<
1304 Instance,
const std::list<Instance>, inlined_capacity>();
1307 SCOPED_TRACE(
"std::vector");
1308 InstanceRangedConstructorTestForContainer<Instance, std::vector<Instance>,
1309 inlined_capacity>();
1312 SCOPED_TRACE(
"const std::vector");
1313 InstanceRangedConstructorTestForContainer<
1314 Instance,
const std::vector<Instance>, inlined_capacity>();
1320 using Instance = TypeParam;
1321 SCOPED_TRACE(
"capacity=1");
1322 InstanceRangedConstructorTestWithCapacity<Instance, 1>();
1323 SCOPED_TRACE(
"capacity=2");
1324 InstanceRangedConstructorTestWithCapacity<Instance, 2>();
1327 TEST(RangedConstructor, ElementsAreConstructed) {
1328 std::vector<std::string> source_v = {
"cat",
"dog"};
1333 EXPECT_EQ(
"cat", v[0]);
1334 EXPECT_EQ(
"dog", v[1]);
1337 TEST(RangedAssign, SimpleType) {
1340 for (
size_t original_size = 0; original_size <= 5; ++original_size) {
1341 SCOPED_TRACE(original_size);
1343 std::vector<int> original_contents(original_size, 12345);
1345 for (
size_t target_size = 0; target_size <= 5; ++target_size) {
1346 SCOPED_TRACE(target_size);
1349 std::vector<int> new_contents;
1350 for (
size_t i = 0; i < target_size; ++
i) {
1351 new_contents.push_back(i + 3);
1355 original_contents.end());
1356 v.assign(new_contents.begin(), new_contents.end());
1358 EXPECT_EQ(new_contents.size(), v.size());
1359 EXPECT_LE(new_contents.size(), v.capacity());
1360 if (target_size <= 3 && original_size <= 3) {
1362 EXPECT_EQ(3, v.capacity());
1364 EXPECT_THAT(v, ElementsAreArray(new_contents));
1370 template <
typename Instance>
1371 static bool InstanceValuesEqual(
const Instance& lhs,
const Instance& rhs) {
1372 return lhs.value() == rhs.value();
1377 template <
typename Instance,
typename SourceContainer>
1378 void InstanceRangedAssignTestForContainer() {
1381 for (
size_t original_size = 0; original_size <= 5; ++original_size) {
1382 SCOPED_TRACE(original_size);
1384 std::vector<Instance> original_contents(original_size, Instance(12345));
1386 for (
size_t target_size = 0; target_size <= 5; ++target_size) {
1387 SCOPED_TRACE(target_size);
1393 std::vector<Instance> new_contents_in;
1394 for (
size_t i = 0; i < target_size; ++
i) {
1395 new_contents_in.push_back(Instance(i + 3));
1397 SourceContainer new_contents(new_contents_in.begin(),
1398 new_contents_in.end());
1401 original_contents.end());
1402 v.assign(new_contents.begin(), new_contents.end());
1404 EXPECT_EQ(new_contents.size(), v.size());
1405 EXPECT_LE(new_contents.size(), v.capacity());
1406 if (target_size <= 3 && original_size <= 3) {
1408 EXPECT_EQ(3, v.capacity());
1410 EXPECT_TRUE(std::equal(v.begin(), v.end(), new_contents.begin(),
1411 InstanceValuesEqual<Instance>));
1417 using Instance = TypeParam;
1420 SCOPED_TRACE(
"std::list");
1421 InstanceRangedAssignTestForContainer<Instance, std::list<Instance>>();
1422 SCOPED_TRACE(
"const std::list");
1423 InstanceRangedAssignTestForContainer<Instance, const std::list<Instance>>();
1424 SCOPED_TRACE(
"std::vector");
1425 InstanceRangedAssignTestForContainer<Instance, std::vector<Instance>>();
1426 SCOPED_TRACE(
"const std::vector");
1427 InstanceRangedAssignTestForContainer<Instance, const std::vector<Instance>>();
1430 TEST(InitializerListConstructor, SimpleTypeWithInlineBacking) {
1432 AllOf(SizeIs(3), CapacityIs(4), ElementsAre(4, 5, 6)));
1435 TEST(InitializerListConstructor, SimpleTypeWithReallocationRequired) {
1437 AllOf(SizeIs(3), CapacityIs(Gt(2)), ElementsAre(4, 5, 6)));
1440 TEST(InitializerListConstructor, DisparateTypesInList) {
1444 ElementsAre(
"foo",
"bar"));
1447 TEST(InitializerListConstructor, ComplexTypeWithInlineBacking) {
1449 CopyableMovableInstance(0)}),
1450 AllOf(SizeIs(1), CapacityIs(1), ElementsAre(ValueIs(0))));
1453 TEST(InitializerListConstructor, ComplexTypeWithReallocationRequired) {
1456 CopyableMovableInstance(0), CopyableMovableInstance(1)}),
1457 AllOf(SizeIs(2), CapacityIs(Gt(1)), ElementsAre(ValueIs(0), ValueIs(1))));
1460 TEST(InitializerListAssign, SimpleTypeFitsInlineBacking) {
1461 for (
size_t original_size = 0; original_size <= 4; ++original_size) {
1462 SCOPED_TRACE(original_size);
1465 const size_t original_capacity_v1 = v1.capacity();
1468 v1,
AllOf(SizeIs(1), CapacityIs(original_capacity_v1), ElementsAre(3)));
1471 const size_t original_capacity_v2 = v2.capacity();
1474 v2,
AllOf(SizeIs(1), CapacityIs(original_capacity_v2), ElementsAre(3)));
1478 TEST(InitializerListAssign, SimpleTypeDoesNotFitInlineBacking) {
1479 for (
size_t original_size = 0; original_size <= 4; ++original_size) {
1480 SCOPED_TRACE(original_size);
1482 v1.assign({3, 4, 5});
1483 EXPECT_THAT(v1,
AllOf(SizeIs(3), ElementsAre(3, 4, 5)));
1484 EXPECT_LE(3, v1.capacity());
1488 EXPECT_THAT(v2,
AllOf(SizeIs(3), ElementsAre(3, 4, 5)));
1489 EXPECT_LE(3, v2.capacity());
1493 TEST(InitializerListAssign, DisparateTypesInList) {
1495 v_int1.
assign({-7, 8ULL});
1496 EXPECT_THAT(v_int1, ElementsAre(-7, 8));
1499 v_int2 = {-7, 8ULL};
1500 EXPECT_THAT(v_int2, ElementsAre(-7, 8));
1503 v_string1.
assign({
"foo", std::string(
"bar")});
1504 EXPECT_THAT(v_string1, ElementsAre(
"foo",
"bar"));
1507 v_string2 = {
"foo", std::string(
"bar")};
1508 EXPECT_THAT(v_string2, ElementsAre(
"foo",
"bar"));
1512 using Instance = TypeParam;
1513 for (
size_t original_size = 0; original_size <= 4; ++original_size) {
1514 SCOPED_TRACE(original_size);
1516 const size_t original_capacity = v.capacity();
1517 v.assign({Instance(3)});
1518 EXPECT_THAT(v,
AllOf(SizeIs(1), CapacityIs(original_capacity),
1519 ElementsAre(ValueIs(3))));
1521 for (
size_t original_size = 0; original_size <= 4; ++original_size) {
1522 SCOPED_TRACE(original_size);
1524 v.assign({Instance(3), Instance(4), Instance(5)});
1525 EXPECT_THAT(v,
AllOf(SizeIs(3),
1526 ElementsAre(ValueIs(3), ValueIs(4), ValueIs(5))));
1527 EXPECT_LE(3, v.capacity());
1532 CountConstructorsDestructorsOnCopyConstruction,
1533 CountConstructorsDestructorsOnMoveConstruction,
1534 CountConstructorsDestructorsOnAssignment,
1535 CountConstructorsDestructorsOnMoveAssignment,
1536 CountElemAssignInlineBacking, RangedConstructor,
1537 RangedAssign, InitializerListAssign);
1539 using InstanceTypes =
1540 ::testing::Types<CopyableOnlyInstance, CopyableMovableInstance>;
1541 INSTANTIATE_TYPED_TEST_CASE_P(InstanceTestOnTypes, InstanceTest, InstanceTypes);
1543 TEST(DynamicVec, DynamicVecCompiles) {
1548 TEST(AllocatorSupportTest, Constructors) {
1549 using MyAlloc = CountingAllocator<int>;
1551 const int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
1552 int64_t allocated = 0;
1553 MyAlloc
alloc(&allocated);
1564 TEST(AllocatorSupportTest, CountAllocations) {
1565 using MyAlloc = CountingAllocator<int>;
1567 const int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
1568 int64_t allocated = 0;
1569 MyAlloc
alloc(&allocated);
1572 EXPECT_THAT(allocated, 0);
1574 EXPECT_THAT(allocated, 0);
1577 EXPECT_THAT(allocated, v.size() *
sizeof(int));
1579 EXPECT_THAT(allocated, 0);
1582 EXPECT_THAT(allocated, 0);
1584 int64_t allocated2 = 0;
1585 MyAlloc alloc2(&allocated2);
1586 AllocVec v2(v, alloc2);
1587 EXPECT_THAT(allocated2, 0);
1589 int64_t allocated3 = 0;
1590 MyAlloc alloc3(&allocated3);
1592 EXPECT_THAT(allocated3, 0);
1594 EXPECT_THAT(allocated, 0);
1597 EXPECT_THAT(allocated, v.size() *
sizeof(int));
1599 int64_t allocated2 = 0;
1600 MyAlloc alloc2(&allocated2);
1601 AllocVec v2(v, alloc2);
1602 EXPECT_THAT(allocated2, v2.size() *
sizeof(int));
1604 int64_t allocated3 = 0;
1605 MyAlloc alloc3(&allocated3);
1607 EXPECT_THAT(allocated3, v3.size() *
sizeof(int));
1609 EXPECT_EQ(allocated, 0);
1613 EXPECT_EQ(allocated, 8 *
sizeof(
int));
1615 EXPECT_EQ(allocated, 8 *
sizeof(
int));
1617 EXPECT_EQ(allocated, 5 *
sizeof(
int));
1619 EXPECT_EQ(allocated, 5 *
sizeof(
int));
1621 EXPECT_EQ(allocated, 0);
1625 TEST(AllocatorSupportTest, SwapBothAllocated) {
1626 using MyAlloc = CountingAllocator<int>;
1628 int64_t allocated1 = 0;
1629 int64_t allocated2 = 0;
1631 const int ia1[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
1632 const int ia2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
1633 MyAlloc
a1(&allocated1);
1634 MyAlloc
a2(&allocated2);
1637 EXPECT_LT(v1.capacity(), v2.capacity());
1638 EXPECT_THAT(allocated1, v1.capacity() *
sizeof(int));
1639 EXPECT_THAT(allocated2, v2.capacity() *
sizeof(int));
1641 EXPECT_THAT(v1, ElementsAreArray(ia2));
1642 EXPECT_THAT(v2, ElementsAreArray(ia1));
1643 EXPECT_THAT(allocated1, v2.capacity() *
sizeof(int));
1644 EXPECT_THAT(allocated2, v1.capacity() *
sizeof(int));
1646 EXPECT_THAT(allocated1, 0);
1647 EXPECT_THAT(allocated2, 0);
1650 TEST(AllocatorSupportTest, SwapOneAllocated) {
1651 using MyAlloc = CountingAllocator<int>;
1653 int64_t allocated1 = 0;
1654 int64_t allocated2 = 0;
1656 const int ia1[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
1657 const int ia2[] = { 0, 1, 2, 3 };
1658 MyAlloc
a1(&allocated1);
1659 MyAlloc
a2(&allocated2);
1662 EXPECT_THAT(allocated1, v1.capacity() *
sizeof(int));
1663 EXPECT_THAT(allocated2, 0);
1665 EXPECT_THAT(v1, ElementsAreArray(ia2));
1666 EXPECT_THAT(v2, ElementsAreArray(ia1));
1667 EXPECT_THAT(allocated1, v2.capacity() *
sizeof(int));
1668 EXPECT_THAT(allocated2, 0);
1669 EXPECT_TRUE(v2.get_allocator() ==
a1);
1670 EXPECT_TRUE(v1.get_allocator() ==
a2);
1672 EXPECT_THAT(allocated1, 0);
1673 EXPECT_THAT(allocated2, 0);
1676 TEST(AllocatorSupportTest, ScopedAllocatorWorks) {
1677 using StdVector = std::vector<int, CountingAllocator<int>>;
1679 std::scoped_allocator_adaptor<CountingAllocator<StdVector>>;
1684 int64_t test_allocated = 0;
1685 StdVector
v(CountingAllocator<int>{&test_allocated});
1687 auto default_std_vec_allocated = test_allocated;
1691 int64_t one_element_std_vec_copy_allocated = test_allocated;
1693 int64_t allocated = 0;
1694 AllocVec vec(MyAlloc{CountingAllocator<StdVector>{&allocated}});
1695 EXPECT_EQ(allocated, 0);
1701 auto expected = default_std_vec_allocated;
1703 EXPECT_EQ(allocated, expected);
1709 expected +=
sizeof(int);
1711 EXPECT_EQ(allocated, expected);
1714 expected += one_element_std_vec_copy_allocated;
1716 EXPECT_EQ(allocated, expected);
1720 expected +=
sizeof(StdVector) * 8 + default_std_vec_allocated * 3;
1722 EXPECT_EQ(allocated, expected);
1725 expected += one_element_std_vec_copy_allocated;
1727 EXPECT_EQ(allocated, expected);
1731 expected +=
sizeof(int);
1733 EXPECT_EQ(allocated, expected);
1736 EXPECT_EQ(allocated, 0);
1739 TEST(AllocatorSupportTest, SizeAllocConstructor) {
1740 constexpr
int inlined_size = 4;
1741 using Alloc = CountingAllocator<int>;
1745 auto len = inlined_size / 2;
1746 int64_t allocated = 0;
1747 auto v = AllocVec(len, Alloc(&allocated));
1750 EXPECT_THAT(allocated, 0);
1751 EXPECT_THAT(v,
AllOf(SizeIs(len), Each(0)));
1755 auto len = inlined_size * 2;
1756 int64_t allocated = 0;
1757 auto v = AllocVec(len, Alloc(&allocated));
1760 EXPECT_THAT(allocated, len *
sizeof(
int));
1761 EXPECT_THAT(v,
AllOf(SizeIs(len), Each(0)));
1765 TEST(InlinedVectorTest, AbslHashValueWorks) {
1767 std::vector<V> cases;
1771 for (
int i = 0; i < 10; ++
i) {
1773 for (
int j = 0; j <
i; ++j) {
iterator emplace(const_iterator pos, Args &&...args)
#define ABSL_ATTRIBUTE_UNUSED
TYPED_TEST_SUITE_P(ConstructorTest)
reference emplace_back(Args &&...args)
void reserve(size_type n)
#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text)
iterator insert(const_iterator pos, const_reference v)
#define ABSL_RAW_CHECK(condition, message)
bool operator==(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
void Swap(T &lhs, T &rhs) noexcept(IsNothrowSwappable< T >::value)
size_type capacity() const noexcept
size_type size() const noexcept
void swap(absl::InlinedVector< T, N, A > &a, absl::InlinedVector< T, N, A > &b) noexcept(noexcept(a.swap(b)))
ABSL_MUST_USE_RESULT testing::AssertionResult VerifyTypeImplementsAbslHashCorrectly(const Container &values)
void assign(size_type n, const_reference v)
#define ABSL_ARRAYSIZE(array)
TYPED_TEST_P(ConstructorTest, NoArgs)
TEST(Symbolize, Unimplemented)
std::unique_ptr< unsigned char[]> p_
std::allocator< int > alloc
iterator begin() noexcept
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
REGISTER_TYPED_TEST_CASE_P(ConstructorTest, NoArgs, BucketCount, BucketCountHash, BucketCountHashEqual, BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, Alloc, InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc, InputIteratorBucketHashAlloc, CopyConstructor, CopyConstructorAlloc, MoveConstructor, MoveConstructorAlloc, InitializerListBucketHashEqualAlloc, InitializerListBucketAlloc, InitializerListBucketHashAlloc, Assignment, MoveAssignment, AssignmentFromInitializerList, AssignmentOverwritesExisting, MoveAssignmentOverwritesExisting, AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf)
void push_back(const_reference v)
iterator erase(const_iterator pos)