abseil-cpp/absl/container/inlined_vector_test.cc
Go to the documentation of this file.
1 // Copyright 2019 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/container/inlined_vector.h"
16 
17 #include <algorithm>
18 #include <forward_list>
19 #include <list>
20 #include <memory>
21 #include <scoped_allocator>
22 #include <sstream>
23 #include <stdexcept>
24 #include <string>
25 #include <vector>
26 
27 #include "gmock/gmock.h"
28 #include "gtest/gtest.h"
29 #include "absl/base/attributes.h"
30 #include "absl/base/internal/exception_testing.h"
31 #include "absl/base/internal/raw_logging.h"
32 #include "absl/base/macros.h"
33 #include "absl/base/options.h"
34 #include "absl/container/internal/counting_allocator.h"
35 #include "absl/container/internal/test_instance_tracker.h"
36 #include "absl/hash/hash_testing.h"
37 #include "absl/memory/memory.h"
38 #include "absl/strings/str_cat.h"
39 
40 namespace {
41 
46 using testing::AllOf;
47 using testing::Each;
50 using testing::Eq;
51 using testing::Gt;
53 
54 using IntVec = absl::InlinedVector<int, 8>;
55 
56 MATCHER_P(SizeIs, n, "") {
57  return testing::ExplainMatchResult(n, arg.size(), result_listener);
58 }
59 
60 MATCHER_P(CapacityIs, n, "") {
61  return testing::ExplainMatchResult(n, arg.capacity(), result_listener);
62 }
63 
64 MATCHER_P(ValueIs, e, "") {
65  return testing::ExplainMatchResult(e, arg.value(), result_listener);
66 }
67 
68 // TODO(bsamwel): Add support for movable-only types.
69 
70 // Test fixture for typed tests on BaseCountedInstance derived classes, see
71 // test_instance_tracker.h.
72 template <typename T>
73 class InstanceTest : public ::testing::Test {};
74 TYPED_TEST_SUITE_P(InstanceTest);
75 
76 // A simple reference counted class to make sure that the proper elements are
77 // destroyed in the erase(begin, end) test.
78 class RefCounted {
79  public:
80  RefCounted(int value, int* count) : value_(value), count_(count) { Ref(); }
81 
82  RefCounted(const RefCounted& v) : value_(v.value_), count_(v.count_) {
83  Ref();
84  }
85 
86  ~RefCounted() {
87  Unref();
88  count_ = nullptr;
89  }
90 
91  friend void swap(RefCounted& a, RefCounted& b) {
92  using std::swap;
93  swap(a.value_, b.value_);
94  swap(a.count_, b.count_);
95  }
96 
97  RefCounted& operator=(RefCounted v) {
98  using std::swap;
99  swap(*this, v);
100  return *this;
101  }
102 
103  void Ref() const {
104  ABSL_RAW_CHECK(count_ != nullptr, "");
105  ++(*count_);
106  }
107 
108  void Unref() const {
109  --(*count_);
110  ABSL_RAW_CHECK(*count_ >= 0, "");
111  }
112 
113  int value_;
114  int* count_;
115 };
116 
117 using RefCountedVec = absl::InlinedVector<RefCounted, 8>;
118 
119 // A class with a vtable pointer
120 class Dynamic {
121  public:
122  virtual ~Dynamic() {}
123 };
124 
125 using DynamicVec = absl::InlinedVector<Dynamic, 8>;
126 
127 // Append 0..len-1 to *v
128 template <typename Container>
129 static void Fill(Container* v, int len, int offset = 0) {
130  for (int i = 0; i < len; i++) {
131  v->push_back(i + offset);
132  }
133 }
134 
135 static IntVec Fill(int len, int offset = 0) {
136  IntVec v;
137  Fill(&v, len, offset);
138  return v;
139 }
140 
141 TEST(IntVec, SimpleOps) {
142  for (int len = 0; len < 20; len++) {
143  IntVec v;
144  const IntVec& cv = v; // const alias
145 
146  Fill(&v, len);
147  EXPECT_EQ(len, v.size());
148  EXPECT_LE(len, v.capacity());
149 
150  for (int i = 0; i < len; i++) {
151  EXPECT_EQ(i, v[i]);
152  EXPECT_EQ(i, v.at(i));
153  }
154  EXPECT_EQ(v.begin(), v.data());
155  EXPECT_EQ(cv.begin(), cv.data());
156 
157  int counter = 0;
158  for (IntVec::iterator iter = v.begin(); iter != v.end(); ++iter) {
160  counter++;
161  }
163 
164  counter = 0;
165  for (IntVec::const_iterator iter = v.begin(); iter != v.end(); ++iter) {
167  counter++;
168  }
170 
171  counter = 0;
172  for (IntVec::const_iterator iter = v.cbegin(); iter != v.cend(); ++iter) {
174  counter++;
175  }
177 
178  if (len > 0) {
179  EXPECT_EQ(0, v.front());
180  EXPECT_EQ(len - 1, v.back());
181  v.pop_back();
182  EXPECT_EQ(len - 1, v.size());
183  for (int i = 0; i < v.size(); ++i) {
184  EXPECT_EQ(i, v[i]);
185  EXPECT_EQ(i, v.at(i));
186  }
187  }
188  }
189 }
190 
191 TEST(IntVec, PopBackNoOverflow) {
192  IntVec v = {1};
193  v.pop_back();
194  EXPECT_EQ(v.size(), 0);
195 }
196 
197 TEST(IntVec, AtThrows) {
198  IntVec v = {1, 2, 3};
199  EXPECT_EQ(v.at(2), 3);
200  ABSL_BASE_INTERNAL_EXPECT_FAIL(v.at(3), std::out_of_range,
201  "failed bounds check");
202 }
203 
204 TEST(IntVec, ReverseIterator) {
205  for (int len = 0; len < 20; len++) {
206  IntVec v;
207  Fill(&v, len);
208 
209  int counter = len;
210  for (IntVec::reverse_iterator iter = v.rbegin(); iter != v.rend(); ++iter) {
211  counter--;
213  }
214  EXPECT_EQ(counter, 0);
215 
216  counter = len;
217  for (IntVec::const_reverse_iterator iter = v.rbegin(); iter != v.rend();
218  ++iter) {
219  counter--;
221  }
222  EXPECT_EQ(counter, 0);
223 
224  counter = len;
225  for (IntVec::const_reverse_iterator iter = v.crbegin(); iter != v.crend();
226  ++iter) {
227  counter--;
229  }
230  EXPECT_EQ(counter, 0);
231  }
232 }
233 
234 TEST(IntVec, Erase) {
235  for (int len = 1; len < 20; len++) {
236  for (int i = 0; i < len; ++i) {
237  IntVec v;
238  Fill(&v, len);
239  v.erase(v.begin() + i);
240  EXPECT_EQ(len - 1, v.size());
241  for (int j = 0; j < i; ++j) {
242  EXPECT_EQ(j, v[j]);
243  }
244  for (int j = i; j < len - 1; ++j) {
245  EXPECT_EQ(j + 1, v[j]);
246  }
247  }
248  }
249 }
250 
251 TEST(IntVec, Hardened) {
252  IntVec v;
253  Fill(&v, 10);
254  EXPECT_EQ(v[9], 9);
255 #if !defined(NDEBUG) || ABSL_OPTION_HARDENED
256  EXPECT_DEATH_IF_SUPPORTED(v[10], "");
257  EXPECT_DEATH_IF_SUPPORTED(v[-1], "");
258 #endif
259 }
260 
261 // At the end of this test loop, the elements between [erase_begin, erase_end)
262 // should have reference counts == 0, and all others elements should have
263 // reference counts == 1.
264 TEST(RefCountedVec, EraseBeginEnd) {
265  for (int len = 1; len < 20; ++len) {
266  for (int erase_begin = 0; erase_begin < len; ++erase_begin) {
267  for (int erase_end = erase_begin; erase_end <= len; ++erase_end) {
268  std::vector<int> counts(len, 0);
269  RefCountedVec v;
270  for (int i = 0; i < len; ++i) {
271  v.push_back(RefCounted(i, &counts[i]));
272  }
273 
274  int erase_len = erase_end - erase_begin;
275 
276  v.erase(v.begin() + erase_begin, v.begin() + erase_end);
277 
278  EXPECT_EQ(len - erase_len, v.size());
279 
280  // Check the elements before the first element erased.
281  for (int i = 0; i < erase_begin; ++i) {
282  EXPECT_EQ(i, v[i].value_);
283  }
284 
285  // Check the elements after the first element erased.
286  for (int i = erase_begin; i < v.size(); ++i) {
287  EXPECT_EQ(i + erase_len, v[i].value_);
288  }
289 
290  // Check that the elements at the beginning are preserved.
291  for (int i = 0; i < erase_begin; ++i) {
292  EXPECT_EQ(1, counts[i]);
293  }
294 
295  // Check that the erased elements are destroyed
296  for (int i = erase_begin; i < erase_end; ++i) {
297  EXPECT_EQ(0, counts[i]);
298  }
299 
300  // Check that the elements at the end are preserved.
301  for (int i = erase_end; i < len; ++i) {
302  EXPECT_EQ(1, counts[i]);
303  }
304  }
305  }
306  }
307 }
308 
309 struct NoDefaultCtor {
310  explicit NoDefaultCtor(int) {}
311 };
312 struct NoCopy {
313  NoCopy() {}
314  NoCopy(const NoCopy&) = delete;
315 };
316 struct NoAssign {
317  NoAssign() {}
318  NoAssign& operator=(const NoAssign&) = delete;
319 };
320 struct MoveOnly {
321  MoveOnly() {}
322  MoveOnly(MoveOnly&&) = default;
323  MoveOnly& operator=(MoveOnly&&) = default;
324 };
325 TEST(InlinedVectorTest, NoDefaultCtor) {
326  absl::InlinedVector<NoDefaultCtor, 1> v(10, NoDefaultCtor(2));
327  (void)v;
328 }
329 TEST(InlinedVectorTest, NoCopy) {
331  (void)v;
332 }
333 TEST(InlinedVectorTest, NoAssign) {
335  (void)v;
336 }
337 TEST(InlinedVectorTest, MoveOnly) {
339  v.push_back(MoveOnly{});
340  v.push_back(MoveOnly{});
341  v.push_back(MoveOnly{});
342  v.erase(v.begin());
343  v.push_back(MoveOnly{});
344  v.erase(v.begin(), v.begin() + 1);
345  v.insert(v.begin(), MoveOnly{});
346  v.emplace(v.begin());
347  v.emplace(v.begin(), MoveOnly{});
348 }
349 TEST(InlinedVectorTest, Noexcept) {
351  EXPECT_TRUE((std::is_nothrow_move_constructible<
353 
354  struct MoveCanThrow {
355  MoveCanThrow(MoveCanThrow&&) {}
356  };
358  (std::is_nothrow_move_constructible<
360 }
361 
362 TEST(InlinedVectorTest, EmplaceBack) {
364 
365  auto& inlined_element = v.emplace_back("answer", 42);
366  EXPECT_EQ(&inlined_element, &v[0]);
367  EXPECT_EQ(inlined_element.first, "answer");
368  EXPECT_EQ(inlined_element.second, 42);
369 
370  auto& allocated_element = v.emplace_back("taxicab", 1729);
371  EXPECT_EQ(&allocated_element, &v[1]);
372  EXPECT_EQ(allocated_element.first, "taxicab");
373  EXPECT_EQ(allocated_element.second, 1729);
374 }
375 
376 TEST(InlinedVectorTest, ShrinkToFitGrowingVector) {
378 
379  v.shrink_to_fit();
380  EXPECT_EQ(v.capacity(), 1);
381 
382  v.emplace_back("answer", 42);
383  v.shrink_to_fit();
384  EXPECT_EQ(v.capacity(), 1);
385 
386  v.emplace_back("taxicab", 1729);
387  EXPECT_GE(v.capacity(), 2);
388  v.shrink_to_fit();
389  EXPECT_EQ(v.capacity(), 2);
390 
391  v.reserve(100);
392  EXPECT_GE(v.capacity(), 100);
393  v.shrink_to_fit();
394  EXPECT_EQ(v.capacity(), 2);
395 }
396 
397 TEST(InlinedVectorTest, ShrinkToFitEdgeCases) {
398  {
400  v.emplace_back("answer", 42);
401  v.emplace_back("taxicab", 1729);
402  EXPECT_GE(v.capacity(), 2);
403  v.pop_back();
404  v.shrink_to_fit();
405  EXPECT_EQ(v.capacity(), 1);
406  EXPECT_EQ(v[0].first, "answer");
407  EXPECT_EQ(v[0].second, 42);
408  }
409 
410  {
412  v.resize(0);
413  v.shrink_to_fit();
414  EXPECT_EQ(v.capacity(), 2); // inlined capacity
415  }
416 
417  {
419  v.resize(1);
420  v.shrink_to_fit();
421  EXPECT_EQ(v.capacity(), 2); // inlined capacity
422  }
423 
424  {
426  v.resize(2);
427  v.shrink_to_fit();
428  EXPECT_EQ(v.capacity(), 2);
429  }
430 
431  {
433  v.resize(3);
434  v.shrink_to_fit();
435  EXPECT_EQ(v.capacity(), 3);
436  }
437 }
438 
439 TEST(IntVec, Insert) {
440  for (int len = 0; len < 20; len++) {
441  for (int pos = 0; pos <= len; pos++) {
442  {
443  // Single element
444  std::vector<int> std_v;
445  Fill(&std_v, len);
446  IntVec v;
447  Fill(&v, len);
448 
449  std_v.insert(std_v.begin() + pos, 9999);
450  IntVec::iterator it = v.insert(v.cbegin() + pos, 9999);
451  EXPECT_THAT(v, ElementsAreArray(std_v));
452  EXPECT_EQ(it, v.cbegin() + pos);
453  }
454  {
455  // n elements
456  std::vector<int> std_v;
457  Fill(&std_v, len);
458  IntVec v;
459  Fill(&v, len);
460 
461  IntVec::size_type n = 5;
462  std_v.insert(std_v.begin() + pos, n, 9999);
463  IntVec::iterator it = v.insert(v.cbegin() + pos, n, 9999);
464  EXPECT_THAT(v, ElementsAreArray(std_v));
465  EXPECT_EQ(it, v.cbegin() + pos);
466  }
467  {
468  // Iterator range (random access iterator)
469  std::vector<int> std_v;
470  Fill(&std_v, len);
471  IntVec v;
472  Fill(&v, len);
473 
474  const std::vector<int> input = {9999, 8888, 7777};
475  std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend());
477  v.insert(v.cbegin() + pos, input.cbegin(), input.cend());
478  EXPECT_THAT(v, ElementsAreArray(std_v));
479  EXPECT_EQ(it, v.cbegin() + pos);
480  }
481  {
482  // Iterator range (forward iterator)
483  std::vector<int> std_v;
484  Fill(&std_v, len);
485  IntVec v;
486  Fill(&v, len);
487 
488  const std::forward_list<int> input = {9999, 8888, 7777};
489  std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend());
491  v.insert(v.cbegin() + pos, input.cbegin(), input.cend());
492  EXPECT_THAT(v, ElementsAreArray(std_v));
493  EXPECT_EQ(it, v.cbegin() + pos);
494  }
495  {
496  // Iterator range (input iterator)
497  std::vector<int> std_v;
498  Fill(&std_v, len);
499  IntVec v;
500  Fill(&v, len);
501 
502  std_v.insert(std_v.begin() + pos, {9999, 8888, 7777});
503  std::istringstream input("9999 8888 7777");
505  v.insert(v.cbegin() + pos, std::istream_iterator<int>(input),
506  std::istream_iterator<int>());
507  EXPECT_THAT(v, ElementsAreArray(std_v));
508  EXPECT_EQ(it, v.cbegin() + pos);
509  }
510  {
511  // Initializer list
512  std::vector<int> std_v;
513  Fill(&std_v, len);
514  IntVec v;
515  Fill(&v, len);
516 
517  std_v.insert(std_v.begin() + pos, {9999, 8888});
518  IntVec::iterator it = v.insert(v.cbegin() + pos, {9999, 8888});
519  EXPECT_THAT(v, ElementsAreArray(std_v));
520  EXPECT_EQ(it, v.cbegin() + pos);
521  }
522  }
523  }
524 }
525 
526 TEST(RefCountedVec, InsertConstructorDestructor) {
527  // Make sure the proper construction/destruction happen during insert
528  // operations.
529  for (int len = 0; len < 20; len++) {
530  SCOPED_TRACE(len);
531  for (int pos = 0; pos <= len; pos++) {
532  SCOPED_TRACE(pos);
533  std::vector<int> counts(len, 0);
534  int inserted_count = 0;
535  RefCountedVec v;
536  for (int i = 0; i < len; ++i) {
537  SCOPED_TRACE(i);
538  v.push_back(RefCounted(i, &counts[i]));
539  }
540 
541  EXPECT_THAT(counts, Each(Eq(1)));
542 
543  RefCounted insert_element(9999, &inserted_count);
544  EXPECT_EQ(1, inserted_count);
545  v.insert(v.begin() + pos, insert_element);
546  EXPECT_EQ(2, inserted_count);
547  // Check that the elements at the end are preserved.
548  EXPECT_THAT(counts, Each(Eq(1)));
549  EXPECT_EQ(2, inserted_count);
550  }
551  }
552 }
553 
554 TEST(IntVec, Resize) {
555  for (int len = 0; len < 20; len++) {
556  IntVec v;
557  Fill(&v, len);
558 
559  // Try resizing up and down by k elements
560  static const int kResizeElem = 1000000;
561  for (int k = 0; k < 10; k++) {
562  // Enlarging resize
563  v.resize(len + k, kResizeElem);
564  EXPECT_EQ(len + k, v.size());
565  EXPECT_LE(len + k, v.capacity());
566  for (int i = 0; i < len + k; i++) {
567  if (i < len) {
568  EXPECT_EQ(i, v[i]);
569  } else {
570  EXPECT_EQ(kResizeElem, v[i]);
571  }
572  }
573 
574  // Shrinking resize
575  v.resize(len, kResizeElem);
576  EXPECT_EQ(len, v.size());
577  EXPECT_LE(len, v.capacity());
578  for (int i = 0; i < len; i++) {
579  EXPECT_EQ(i, v[i]);
580  }
581  }
582  }
583 }
584 
585 TEST(IntVec, InitWithLength) {
586  for (int len = 0; len < 20; len++) {
587  IntVec v(len, 7);
588  EXPECT_EQ(len, v.size());
589  EXPECT_LE(len, v.capacity());
590  for (int i = 0; i < len; i++) {
591  EXPECT_EQ(7, v[i]);
592  }
593  }
594 }
595 
596 TEST(IntVec, CopyConstructorAndAssignment) {
597  for (int len = 0; len < 20; len++) {
598  IntVec v;
599  Fill(&v, len);
600  EXPECT_EQ(len, v.size());
601  EXPECT_LE(len, v.capacity());
602 
603  IntVec v2(v);
604  EXPECT_TRUE(v == v2) << PrintToString(v) << PrintToString(v2);
605 
606  for (int start_len = 0; start_len < 20; start_len++) {
607  IntVec v3;
608  Fill(&v3, start_len, 99); // Add dummy elements that should go away
609  v3 = v;
610  EXPECT_TRUE(v == v3) << PrintToString(v) << PrintToString(v3);
611  }
612  }
613 }
614 
615 TEST(IntVec, AliasingCopyAssignment) {
616  for (int len = 0; len < 20; ++len) {
617  IntVec original;
618  Fill(&original, len);
619  IntVec dup = original;
620  dup = *&dup;
621  EXPECT_EQ(dup, original);
622  }
623 }
624 
625 TEST(IntVec, MoveConstructorAndAssignment) {
626  for (int len = 0; len < 20; len++) {
627  IntVec v_in;
628  const int inlined_capacity = v_in.capacity();
629  Fill(&v_in, len);
630  EXPECT_EQ(len, v_in.size());
631  EXPECT_LE(len, v_in.capacity());
632 
633  {
634  IntVec v_temp(v_in);
635  auto* old_data = v_temp.data();
636  IntVec v_out(std::move(v_temp));
637  EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out);
638  if (v_in.size() > inlined_capacity) {
639  // Allocation is moved as a whole, data stays in place.
640  EXPECT_TRUE(v_out.data() == old_data);
641  } else {
642  EXPECT_FALSE(v_out.data() == old_data);
643  }
644  }
645  for (int start_len = 0; start_len < 20; start_len++) {
646  IntVec v_out;
647  Fill(&v_out, start_len, 99); // Add dummy elements that should go away
648  IntVec v_temp(v_in);
649  auto* old_data = v_temp.data();
650  v_out = std::move(v_temp);
651  EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out);
652  if (v_in.size() > inlined_capacity) {
653  // Allocation is moved as a whole, data stays in place.
654  EXPECT_TRUE(v_out.data() == old_data);
655  } else {
656  EXPECT_FALSE(v_out.data() == old_data);
657  }
658  }
659  }
660 }
661 
662 class NotTriviallyDestructible {
663  public:
664  NotTriviallyDestructible() : p_(new int(1)) {}
665  explicit NotTriviallyDestructible(int i) : p_(new int(i)) {}
666 
667  NotTriviallyDestructible(const NotTriviallyDestructible& other)
668  : p_(new int(*other.p_)) {}
669 
670  NotTriviallyDestructible& operator=(const NotTriviallyDestructible& other) {
671  p_ = absl::make_unique<int>(*other.p_);
672  return *this;
673  }
674 
675  bool operator==(const NotTriviallyDestructible& other) const {
676  return *p_ == *other.p_;
677  }
678 
679  private:
680  std::unique_ptr<int> p_;
681 };
682 
683 TEST(AliasingTest, Emplace) {
684  for (int i = 2; i < 20; ++i) {
686  for (int j = 0; j < i; ++j) {
687  vec.push_back(NotTriviallyDestructible(j));
688  }
689  vec.emplace(vec.begin(), vec[0]);
690  EXPECT_EQ(vec[0], vec[1]);
691  vec.emplace(vec.begin() + i / 2, vec[i / 2]);
692  EXPECT_EQ(vec[i / 2], vec[i / 2 + 1]);
693  vec.emplace(vec.end() - 1, vec.back());
694  EXPECT_EQ(vec[vec.size() - 2], vec.back());
695  }
696 }
697 
698 TEST(AliasingTest, InsertWithCount) {
699  for (int i = 1; i < 20; ++i) {
701  for (int j = 0; j < i; ++j) {
702  vec.push_back(NotTriviallyDestructible(j));
703  }
704  for (int n = 0; n < 5; ++n) {
705  // We use back where we can because it's guaranteed to become invalidated
706  vec.insert(vec.begin(), n, vec.back());
707  auto b = vec.begin();
708  EXPECT_TRUE(
709  std::all_of(b, b + n, [&vec](const NotTriviallyDestructible& x) {
710  return x == vec.back();
711  }));
712 
713  auto m_idx = vec.size() / 2;
714  vec.insert(vec.begin() + m_idx, n, vec.back());
715  auto m = vec.begin() + m_idx;
716  EXPECT_TRUE(
717  std::all_of(m, m + n, [&vec](const NotTriviallyDestructible& x) {
718  return x == vec.back();
719  }));
720 
721  // We want distinct values so the equality test is meaningful,
722  // vec[vec.size() - 1] is also almost always invalidated.
723  auto old_e = vec.size() - 1;
724  auto val = vec[old_e];
725  vec.insert(vec.end(), n, vec[old_e]);
726  auto e = vec.begin() + old_e;
727  EXPECT_TRUE(std::all_of(
728  e, e + n,
729  [&val](const NotTriviallyDestructible& x) { return x == val; }));
730  }
731  }
732 }
733 
734 TEST(OverheadTest, Storage) {
735  // Check for size overhead.
736  // In particular, ensure that std::allocator doesn't cost anything to store.
737  // The union should be absorbing some of the allocation bookkeeping overhead
738  // in the larger vectors, leaving only the size_ field as overhead.
739 
740  struct T { void* val; };
741  size_t expected_overhead = sizeof(T);
742 
743  EXPECT_EQ((2 * expected_overhead),
744  sizeof(absl::InlinedVector<T, 1>) - sizeof(T[1]));
745  EXPECT_EQ(expected_overhead,
746  sizeof(absl::InlinedVector<T, 2>) - sizeof(T[2]));
747  EXPECT_EQ(expected_overhead,
748  sizeof(absl::InlinedVector<T, 3>) - sizeof(T[3]));
749  EXPECT_EQ(expected_overhead,
750  sizeof(absl::InlinedVector<T, 4>) - sizeof(T[4]));
751  EXPECT_EQ(expected_overhead,
752  sizeof(absl::InlinedVector<T, 5>) - sizeof(T[5]));
753  EXPECT_EQ(expected_overhead,
754  sizeof(absl::InlinedVector<T, 6>) - sizeof(T[6]));
755  EXPECT_EQ(expected_overhead,
756  sizeof(absl::InlinedVector<T, 7>) - sizeof(T[7]));
757  EXPECT_EQ(expected_overhead,
758  sizeof(absl::InlinedVector<T, 8>) - sizeof(T[8]));
759 }
760 
761 TEST(IntVec, Clear) {
762  for (int len = 0; len < 20; len++) {
763  SCOPED_TRACE(len);
764  IntVec v;
765  Fill(&v, len);
766  v.clear();
767  EXPECT_EQ(0, v.size());
768  EXPECT_EQ(v.begin(), v.end());
769  }
770 }
771 
772 TEST(IntVec, Reserve) {
773  for (int len = 0; len < 20; len++) {
774  IntVec v;
775  Fill(&v, len);
776 
777  for (int newlen = 0; newlen < 100; newlen++) {
778  const int* start_rep = v.data();
779  v.reserve(newlen);
780  const int* final_rep = v.data();
781  if (newlen <= len) {
782  EXPECT_EQ(start_rep, final_rep);
783  }
784  EXPECT_LE(newlen, v.capacity());
785 
786  // Filling up to newlen should not change rep
787  while (v.size() < newlen) {
788  v.push_back(0);
789  }
790  EXPECT_EQ(final_rep, v.data());
791  }
792  }
793 }
794 
795 TEST(StringVec, SelfRefPushBack) {
796  std::vector<std::string> std_v;
798  const std::string s = "A quite long string to ensure heap.";
799  std_v.push_back(s);
800  v.push_back(s);
801  for (int i = 0; i < 20; ++i) {
802  EXPECT_THAT(v, ElementsAreArray(std_v));
803 
804  v.push_back(v.back());
805  std_v.push_back(std_v.back());
806  }
807  EXPECT_THAT(v, ElementsAreArray(std_v));
808 }
809 
810 TEST(StringVec, SelfRefPushBackWithMove) {
811  std::vector<std::string> std_v;
813  const std::string s = "A quite long string to ensure heap.";
814  std_v.push_back(s);
815  v.push_back(s);
816  for (int i = 0; i < 20; ++i) {
817  EXPECT_EQ(v.back(), std_v.back());
818 
819  v.push_back(std::move(v.back()));
820  std_v.push_back(std::move(std_v.back()));
821  }
822  EXPECT_EQ(v.back(), std_v.back());
823 }
824 
825 TEST(StringVec, SelfMove) {
826  const std::string s = "A quite long string to ensure heap.";
827  for (int len = 0; len < 20; len++) {
828  SCOPED_TRACE(len);
830  for (int i = 0; i < len; ++i) {
831  SCOPED_TRACE(i);
832  v.push_back(s);
833  }
834  // Indirection necessary to avoid compiler warning.
835  v = std::move(*(&v));
836  // Ensure that the inlined vector is still in a valid state by copying it.
837  // We don't expect specific contents since a self-move results in an
838  // unspecified valid state.
839  std::vector<std::string> copy(v.begin(), v.end());
840  }
841 }
842 
843 TEST(IntVec, Swap) {
844  for (int l1 = 0; l1 < 20; l1++) {
845  SCOPED_TRACE(l1);
846  for (int l2 = 0; l2 < 20; l2++) {
847  SCOPED_TRACE(l2);
848  IntVec a = Fill(l1, 0);
849  IntVec b = Fill(l2, 100);
850  {
851  using std::swap;
852  swap(a, b);
853  }
854  EXPECT_EQ(l1, b.size());
855  EXPECT_EQ(l2, a.size());
856  for (int i = 0; i < l1; i++) {
857  SCOPED_TRACE(i);
858  EXPECT_EQ(i, b[i]);
859  }
860  for (int i = 0; i < l2; i++) {
861  SCOPED_TRACE(i);
862  EXPECT_EQ(100 + i, a[i]);
863  }
864  }
865  }
866 }
867 
868 TYPED_TEST_P(InstanceTest, Swap) {
869  using Instance = TypeParam;
870  using InstanceVec = absl::InlinedVector<Instance, 8>;
871  for (int l1 = 0; l1 < 20; l1++) {
872  SCOPED_TRACE(l1);
873  for (int l2 = 0; l2 < 20; l2++) {
874  SCOPED_TRACE(l2);
875  InstanceTracker tracker;
876  InstanceVec a, b;
877  const size_t inlined_capacity = a.capacity();
878  auto min_len = std::min(l1, l2);
879  auto max_len = std::max(l1, l2);
880  for (int i = 0; i < l1; i++) a.push_back(Instance(i));
881  for (int i = 0; i < l2; i++) b.push_back(Instance(100 + i));
882  EXPECT_EQ(tracker.instances(), l1 + l2);
883  tracker.ResetCopiesMovesSwaps();
884  {
885  using std::swap;
886  swap(a, b);
887  }
888  EXPECT_EQ(tracker.instances(), l1 + l2);
889  if (a.size() > inlined_capacity && b.size() > inlined_capacity) {
890  EXPECT_EQ(tracker.swaps(), 0); // Allocations are swapped.
891  EXPECT_EQ(tracker.moves(), 0);
892  } else if (a.size() <= inlined_capacity && b.size() <= inlined_capacity) {
893  EXPECT_EQ(tracker.swaps(), min_len);
894  EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()),
895  max_len - min_len);
896  } else {
897  // One is allocated and the other isn't. The allocation is transferred
898  // without copying elements, and the inlined instances are copied/moved.
899  EXPECT_EQ(tracker.swaps(), 0);
900  EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()),
901  min_len);
902  }
903 
904  EXPECT_EQ(l1, b.size());
905  EXPECT_EQ(l2, a.size());
906  for (int i = 0; i < l1; i++) {
907  EXPECT_EQ(i, b[i].value());
908  }
909  for (int i = 0; i < l2; i++) {
910  EXPECT_EQ(100 + i, a[i].value());
911  }
912  }
913  }
914 }
915 
916 TEST(IntVec, EqualAndNotEqual) {
917  IntVec a, b;
918  EXPECT_TRUE(a == b);
919  EXPECT_FALSE(a != b);
920 
921  a.push_back(3);
922  EXPECT_FALSE(a == b);
923  EXPECT_TRUE(a != b);
924 
925  b.push_back(3);
926  EXPECT_TRUE(a == b);
927  EXPECT_FALSE(a != b);
928 
929  b.push_back(7);
930  EXPECT_FALSE(a == b);
931  EXPECT_TRUE(a != b);
932 
933  a.push_back(6);
934  EXPECT_FALSE(a == b);
935  EXPECT_TRUE(a != b);
936 
937  a.clear();
938  b.clear();
939  for (int i = 0; i < 100; i++) {
940  a.push_back(i);
941  b.push_back(i);
942  EXPECT_TRUE(a == b);
943  EXPECT_FALSE(a != b);
944 
945  b[i] = b[i] + 1;
946  EXPECT_FALSE(a == b);
947  EXPECT_TRUE(a != b);
948 
949  b[i] = b[i] - 1; // Back to before
950  EXPECT_TRUE(a == b);
951  EXPECT_FALSE(a != b);
952  }
953 }
954 
955 TEST(IntVec, RelationalOps) {
956  IntVec a, b;
957  EXPECT_FALSE(a < b);
958  EXPECT_FALSE(b < a);
959  EXPECT_FALSE(a > b);
960  EXPECT_FALSE(b > a);
961  EXPECT_TRUE(a <= b);
962  EXPECT_TRUE(b <= a);
963  EXPECT_TRUE(a >= b);
964  EXPECT_TRUE(b >= a);
965  b.push_back(3);
966  EXPECT_TRUE(a < b);
967  EXPECT_FALSE(b < a);
968  EXPECT_FALSE(a > b);
969  EXPECT_TRUE(b > a);
970  EXPECT_TRUE(a <= b);
971  EXPECT_FALSE(b <= a);
972  EXPECT_FALSE(a >= b);
973  EXPECT_TRUE(b >= a);
974 }
975 
976 TYPED_TEST_P(InstanceTest, CountConstructorsDestructors) {
977  using Instance = TypeParam;
978  using InstanceVec = absl::InlinedVector<Instance, 8>;
979  InstanceTracker tracker;
980  for (int len = 0; len < 20; len++) {
981  SCOPED_TRACE(len);
982  tracker.ResetCopiesMovesSwaps();
983 
984  InstanceVec v;
985  const size_t inlined_capacity = v.capacity();
986  for (int i = 0; i < len; i++) {
987  v.push_back(Instance(i));
988  }
989  EXPECT_EQ(tracker.instances(), len);
990  EXPECT_GE(tracker.copies() + tracker.moves(),
991  len); // More due to reallocation.
992  tracker.ResetCopiesMovesSwaps();
993 
994  // Enlarging resize() must construct some objects
995  tracker.ResetCopiesMovesSwaps();
996  v.resize(len + 10, Instance(100));
997  EXPECT_EQ(tracker.instances(), len + 10);
998  if (len <= inlined_capacity && len + 10 > inlined_capacity) {
999  EXPECT_EQ(tracker.copies() + tracker.moves(), 10 + len);
1000  } else {
1001  // Only specify a minimum number of copies + moves. We don't want to
1002  // depend on the reallocation policy here.
1003  EXPECT_GE(tracker.copies() + tracker.moves(),
1004  10); // More due to reallocation.
1005  }
1006 
1007  // Shrinking resize() must destroy some objects
1008  tracker.ResetCopiesMovesSwaps();
1009  v.resize(len, Instance(100));
1010  EXPECT_EQ(tracker.instances(), len);
1011  EXPECT_EQ(tracker.copies(), 0);
1012  EXPECT_EQ(tracker.moves(), 0);
1013 
1014  // reserve() must not increase the number of initialized objects
1015  SCOPED_TRACE("reserve");
1016  v.reserve(len + 1000);
1017  EXPECT_EQ(tracker.instances(), len);
1018  EXPECT_EQ(tracker.copies() + tracker.moves(), len);
1019 
1020  // pop_back() and erase() must destroy one object
1021  if (len > 0) {
1022  tracker.ResetCopiesMovesSwaps();
1023  v.pop_back();
1024  EXPECT_EQ(tracker.instances(), len - 1);
1025  EXPECT_EQ(tracker.copies(), 0);
1026  EXPECT_EQ(tracker.moves(), 0);
1027 
1028  if (!v.empty()) {
1029  tracker.ResetCopiesMovesSwaps();
1030  v.erase(v.begin());
1031  EXPECT_EQ(tracker.instances(), len - 2);
1032  EXPECT_EQ(tracker.copies() + tracker.moves(), len - 2);
1033  }
1034  }
1035 
1036  tracker.ResetCopiesMovesSwaps();
1037  int instances_before_empty_erase = tracker.instances();
1038  v.erase(v.begin(), v.begin());
1039  EXPECT_EQ(tracker.instances(), instances_before_empty_erase);
1040  EXPECT_EQ(tracker.copies() + tracker.moves(), 0);
1041  }
1042 }
1043 
1044 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnCopyConstruction) {
1045  using Instance = TypeParam;
1046  using InstanceVec = absl::InlinedVector<Instance, 8>;
1047  InstanceTracker tracker;
1048  for (int len = 0; len < 20; len++) {
1049  SCOPED_TRACE(len);
1050  tracker.ResetCopiesMovesSwaps();
1051 
1052  InstanceVec v;
1053  for (int i = 0; i < len; i++) {
1054  v.push_back(Instance(i));
1055  }
1056  EXPECT_EQ(tracker.instances(), len);
1057  EXPECT_GE(tracker.copies() + tracker.moves(),
1058  len); // More due to reallocation.
1059  tracker.ResetCopiesMovesSwaps();
1060  { // Copy constructor should create 'len' more instances.
1061  InstanceVec v_copy(v);
1062  EXPECT_EQ(tracker.instances(), len + len);
1063  EXPECT_EQ(tracker.copies(), len);
1064  EXPECT_EQ(tracker.moves(), 0);
1065  }
1066  EXPECT_EQ(tracker.instances(), len);
1067  }
1068 }
1069 
1070 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveConstruction) {
1071  using Instance = TypeParam;
1072  using InstanceVec = absl::InlinedVector<Instance, 8>;
1073  InstanceTracker tracker;
1074  for (int len = 0; len < 20; len++) {
1075  SCOPED_TRACE(len);
1076  tracker.ResetCopiesMovesSwaps();
1077 
1078  InstanceVec v;
1079  const size_t inlined_capacity = v.capacity();
1080  for (int i = 0; i < len; i++) {
1081  v.push_back(Instance(i));
1082  }
1083  EXPECT_EQ(tracker.instances(), len);
1084  EXPECT_GE(tracker.copies() + tracker.moves(),
1085  len); // More due to reallocation.
1086  tracker.ResetCopiesMovesSwaps();
1087  {
1088  InstanceVec v_copy(std::move(v));
1089  if (len > inlined_capacity) {
1090  // Allocation is moved as a whole.
1091  EXPECT_EQ(tracker.instances(), len);
1092  EXPECT_EQ(tracker.live_instances(), len);
1093  // Tests an implementation detail, don't rely on this in your code.
1094  EXPECT_EQ(v.size(), 0); // NOLINT misc-use-after-move
1095  EXPECT_EQ(tracker.copies(), 0);
1096  EXPECT_EQ(tracker.moves(), 0);
1097  } else {
1098  EXPECT_EQ(tracker.instances(), len + len);
1099  if (Instance::supports_move()) {
1100  EXPECT_EQ(tracker.live_instances(), len);
1101  EXPECT_EQ(tracker.copies(), 0);
1102  EXPECT_EQ(tracker.moves(), len);
1103  } else {
1104  EXPECT_EQ(tracker.live_instances(), len + len);
1105  EXPECT_EQ(tracker.copies(), len);
1106  EXPECT_EQ(tracker.moves(), 0);
1107  }
1108  }
1109  EXPECT_EQ(tracker.swaps(), 0);
1110  }
1111  }
1112 }
1113 
1114 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnAssignment) {
1115  using Instance = TypeParam;
1116  using InstanceVec = absl::InlinedVector<Instance, 8>;
1117  InstanceTracker tracker;
1118  for (int len = 0; len < 20; len++) {
1119  SCOPED_TRACE(len);
1120  for (int longorshort = 0; longorshort <= 1; ++longorshort) {
1121  SCOPED_TRACE(longorshort);
1122  tracker.ResetCopiesMovesSwaps();
1123 
1124  InstanceVec longer, shorter;
1125  for (int i = 0; i < len; i++) {
1126  longer.push_back(Instance(i));
1127  shorter.push_back(Instance(i));
1128  }
1129  longer.push_back(Instance(len));
1130  EXPECT_EQ(tracker.instances(), len + len + 1);
1131  EXPECT_GE(tracker.copies() + tracker.moves(),
1132  len + len + 1); // More due to reallocation.
1133 
1134  tracker.ResetCopiesMovesSwaps();
1135  if (longorshort) {
1136  shorter = longer;
1137  EXPECT_EQ(tracker.instances(), (len + 1) + (len + 1));
1138  EXPECT_GE(tracker.copies() + tracker.moves(),
1139  len + 1); // More due to reallocation.
1140  } else {
1141  longer = shorter;
1142  EXPECT_EQ(tracker.instances(), len + len);
1143  EXPECT_EQ(tracker.copies() + tracker.moves(), len);
1144  }
1145  }
1146  }
1147 }
1148 
1149 TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveAssignment) {
1150  using Instance = TypeParam;
1151  using InstanceVec = absl::InlinedVector<Instance, 8>;
1152  InstanceTracker tracker;
1153  for (int len = 0; len < 20; len++) {
1154  SCOPED_TRACE(len);
1155  for (int longorshort = 0; longorshort <= 1; ++longorshort) {
1156  SCOPED_TRACE(longorshort);
1157  tracker.ResetCopiesMovesSwaps();
1158 
1159  InstanceVec longer, shorter;
1160  const int inlined_capacity = longer.capacity();
1161  for (int i = 0; i < len; i++) {
1162  longer.push_back(Instance(i));
1163  shorter.push_back(Instance(i));
1164  }
1165  longer.push_back(Instance(len));
1166  EXPECT_EQ(tracker.instances(), len + len + 1);
1167  EXPECT_GE(tracker.copies() + tracker.moves(),
1168  len + len + 1); // More due to reallocation.
1169 
1170  tracker.ResetCopiesMovesSwaps();
1171  int src_len;
1172  if (longorshort) {
1173  src_len = len + 1;
1174  shorter = std::move(longer);
1175  } else {
1176  src_len = len;
1177  longer = std::move(shorter);
1178  }
1179  if (src_len > inlined_capacity) {
1180  // Allocation moved as a whole.
1181  EXPECT_EQ(tracker.instances(), src_len);
1182  EXPECT_EQ(tracker.live_instances(), src_len);
1183  EXPECT_EQ(tracker.copies(), 0);
1184  EXPECT_EQ(tracker.moves(), 0);
1185  } else {
1186  // Elements are all copied.
1187  EXPECT_EQ(tracker.instances(), src_len + src_len);
1188  if (Instance::supports_move()) {
1189  EXPECT_EQ(tracker.copies(), 0);
1190  EXPECT_EQ(tracker.moves(), src_len);
1191  EXPECT_EQ(tracker.live_instances(), src_len);
1192  } else {
1193  EXPECT_EQ(tracker.copies(), src_len);
1194  EXPECT_EQ(tracker.moves(), 0);
1195  EXPECT_EQ(tracker.live_instances(), src_len + src_len);
1196  }
1197  }
1198  EXPECT_EQ(tracker.swaps(), 0);
1199  }
1200  }
1201 }
1202 
1203 TEST(CountElemAssign, SimpleTypeWithInlineBacking) {
1204  for (size_t original_size = 0; original_size <= 5; ++original_size) {
1205  SCOPED_TRACE(original_size);
1206  // Original contents are [12345, 12345, ...]
1207  std::vector<int> original_contents(original_size, 12345);
1208 
1209  absl::InlinedVector<int, 2> v(original_contents.begin(),
1210  original_contents.end());
1211  v.assign(2, 123);
1212  EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(123, 123)));
1213  if (original_size <= 2) {
1214  // If the original had inline backing, it should stay inline.
1215  EXPECT_EQ(2, v.capacity());
1216  }
1217  }
1218 }
1219 
1220 TEST(CountElemAssign, SimpleTypeWithAllocation) {
1221  for (size_t original_size = 0; original_size <= 5; ++original_size) {
1222  SCOPED_TRACE(original_size);
1223  // Original contents are [12345, 12345, ...]
1224  std::vector<int> original_contents(original_size, 12345);
1225 
1226  absl::InlinedVector<int, 2> v(original_contents.begin(),
1227  original_contents.end());
1228  v.assign(3, 123);
1229  EXPECT_THAT(v, AllOf(SizeIs(3), ElementsAre(123, 123, 123)));
1230  EXPECT_LE(v.size(), v.capacity());
1231  }
1232 }
1233 
1234 TYPED_TEST_P(InstanceTest, CountElemAssignInlineBacking) {
1235  using Instance = TypeParam;
1236  for (size_t original_size = 0; original_size <= 5; ++original_size) {
1237  SCOPED_TRACE(original_size);
1238  // Original contents are [12345, 12345, ...]
1239  std::vector<Instance> original_contents(original_size, Instance(12345));
1240 
1241  absl::InlinedVector<Instance, 2> v(original_contents.begin(),
1242  original_contents.end());
1243  v.assign(2, Instance(123));
1244  EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(ValueIs(123), ValueIs(123))));
1245  if (original_size <= 2) {
1246  // If the original had inline backing, it should stay inline.
1247  EXPECT_EQ(2, v.capacity());
1248  }
1249  }
1250 }
1251 
1252 template <typename Instance>
1253 void InstanceCountElemAssignWithAllocationTest() {
1254  for (size_t original_size = 0; original_size <= 5; ++original_size) {
1255  SCOPED_TRACE(original_size);
1256  // Original contents are [12345, 12345, ...]
1257  std::vector<Instance> original_contents(original_size, Instance(12345));
1258 
1259  absl::InlinedVector<Instance, 2> v(original_contents.begin(),
1260  original_contents.end());
1261  v.assign(3, Instance(123));
1262  EXPECT_THAT(v, AllOf(SizeIs(3), ElementsAre(ValueIs(123), ValueIs(123),
1263  ValueIs(123))));
1264  EXPECT_LE(v.size(), v.capacity());
1265  }
1266 }
1267 TEST(CountElemAssign, WithAllocationCopyableInstance) {
1268  InstanceCountElemAssignWithAllocationTest<CopyableOnlyInstance>();
1269 }
1270 TEST(CountElemAssign, WithAllocationCopyableMovableInstance) {
1271  InstanceCountElemAssignWithAllocationTest<CopyableMovableInstance>();
1272 }
1273 
1274 TEST(RangedConstructor, SimpleType) {
1275  std::vector<int> source_v = {4, 5, 6};
1276  // First try to fit in inline backing
1277  absl::InlinedVector<int, 4> v(source_v.begin(), source_v.end());
1278  EXPECT_EQ(3, v.size());
1279  EXPECT_EQ(4, v.capacity()); // Indication that we're still on inlined storage
1280  EXPECT_EQ(4, v[0]);
1281  EXPECT_EQ(5, v[1]);
1282  EXPECT_EQ(6, v[2]);
1283 
1284  // Now, force a re-allocate
1285  absl::InlinedVector<int, 2> realloc_v(source_v.begin(), source_v.end());
1286  EXPECT_EQ(3, realloc_v.size());
1287  EXPECT_LT(2, realloc_v.capacity());
1288  EXPECT_EQ(4, realloc_v[0]);
1289  EXPECT_EQ(5, realloc_v[1]);
1290  EXPECT_EQ(6, realloc_v[2]);
1291 }
1292 
1293 // Test for ranged constructors using Instance as the element type and
1294 // SourceContainer as the source container type.
1295 template <typename Instance, typename SourceContainer, int inlined_capacity>
1296 void InstanceRangedConstructorTestForContainer() {
1297  InstanceTracker tracker;
1298  SourceContainer source_v = {Instance(0), Instance(1)};
1299  tracker.ResetCopiesMovesSwaps();
1301  source_v.end());
1302  EXPECT_EQ(2, v.size());
1303  EXPECT_LT(1, v.capacity());
1304  EXPECT_EQ(0, v[0].value());
1305  EXPECT_EQ(1, v[1].value());
1306  EXPECT_EQ(tracker.copies(), 2);
1307  EXPECT_EQ(tracker.moves(), 0);
1308 }
1309 
1310 template <typename Instance, int inlined_capacity>
1311 void InstanceRangedConstructorTestWithCapacity() {
1312  // Test with const and non-const, random access and non-random-access sources.
1313  // TODO(bsamwel): Test with an input iterator source.
1314  {
1315  SCOPED_TRACE("std::list");
1316  InstanceRangedConstructorTestForContainer<Instance, std::list<Instance>,
1317  inlined_capacity>();
1318  {
1319  SCOPED_TRACE("const std::list");
1320  InstanceRangedConstructorTestForContainer<
1321  Instance, const std::list<Instance>, inlined_capacity>();
1322  }
1323  {
1324  SCOPED_TRACE("std::vector");
1325  InstanceRangedConstructorTestForContainer<Instance, std::vector<Instance>,
1326  inlined_capacity>();
1327  }
1328  {
1329  SCOPED_TRACE("const std::vector");
1330  InstanceRangedConstructorTestForContainer<
1331  Instance, const std::vector<Instance>, inlined_capacity>();
1332  }
1333  }
1334 }
1335 
1336 TYPED_TEST_P(InstanceTest, RangedConstructor) {
1337  using Instance = TypeParam;
1338  SCOPED_TRACE("capacity=1");
1339  InstanceRangedConstructorTestWithCapacity<Instance, 1>();
1340  SCOPED_TRACE("capacity=2");
1341  InstanceRangedConstructorTestWithCapacity<Instance, 2>();
1342 }
1343 
1344 TEST(RangedConstructor, ElementsAreConstructed) {
1345  std::vector<std::string> source_v = {"cat", "dog"};
1346 
1347  // Force expansion and re-allocation of v. Ensures that when the vector is
1348  // expanded that new elements are constructed.
1349  absl::InlinedVector<std::string, 1> v(source_v.begin(), source_v.end());
1350  EXPECT_EQ("cat", v[0]);
1351  EXPECT_EQ("dog", v[1]);
1352 }
1353 
1354 TEST(RangedAssign, SimpleType) {
1355  // Test for all combinations of original sizes (empty and non-empty inline,
1356  // and out of line) and target sizes.
1357  for (size_t original_size = 0; original_size <= 5; ++original_size) {
1358  SCOPED_TRACE(original_size);
1359  // Original contents are [12345, 12345, ...]
1360  std::vector<int> original_contents(original_size, 12345);
1361 
1362  for (size_t target_size = 0; target_size <= 5; ++target_size) {
1363  SCOPED_TRACE(target_size);
1364 
1365  // New contents are [3, 4, ...]
1366  std::vector<int> new_contents;
1367  for (size_t i = 0; i < target_size; ++i) {
1368  new_contents.push_back(i + 3);
1369  }
1370 
1371  absl::InlinedVector<int, 3> v(original_contents.begin(),
1372  original_contents.end());
1373  v.assign(new_contents.begin(), new_contents.end());
1374 
1375  EXPECT_EQ(new_contents.size(), v.size());
1376  EXPECT_LE(new_contents.size(), v.capacity());
1377  if (target_size <= 3 && original_size <= 3) {
1378  // Storage should stay inline when target size is small.
1379  EXPECT_EQ(3, v.capacity());
1380  }
1381  EXPECT_THAT(v, ElementsAreArray(new_contents));
1382  }
1383  }
1384 }
1385 
1386 // Returns true if lhs and rhs have the same value.
1387 template <typename Instance>
1388 static bool InstanceValuesEqual(const Instance& lhs, const Instance& rhs) {
1389  return lhs.value() == rhs.value();
1390 }
1391 
1392 // Test for ranged assign() using Instance as the element type and
1393 // SourceContainer as the source container type.
1394 template <typename Instance, typename SourceContainer>
1395 void InstanceRangedAssignTestForContainer() {
1396  // Test for all combinations of original sizes (empty and non-empty inline,
1397  // and out of line) and target sizes.
1398  for (size_t original_size = 0; original_size <= 5; ++original_size) {
1399  SCOPED_TRACE(original_size);
1400  // Original contents are [12345, 12345, ...]
1401  std::vector<Instance> original_contents(original_size, Instance(12345));
1402 
1403  for (size_t target_size = 0; target_size <= 5; ++target_size) {
1404  SCOPED_TRACE(target_size);
1405 
1406  // New contents are [3, 4, ...]
1407  // Generate data using a non-const container, because SourceContainer
1408  // itself may be const.
1409  // TODO(bsamwel): Test with an input iterator.
1410  std::vector<Instance> new_contents_in;
1411  for (size_t i = 0; i < target_size; ++i) {
1412  new_contents_in.push_back(Instance(i + 3));
1413  }
1414  SourceContainer new_contents(new_contents_in.begin(),
1415  new_contents_in.end());
1416 
1417  absl::InlinedVector<Instance, 3> v(original_contents.begin(),
1418  original_contents.end());
1419  v.assign(new_contents.begin(), new_contents.end());
1420 
1421  EXPECT_EQ(new_contents.size(), v.size());
1422  EXPECT_LE(new_contents.size(), v.capacity());
1423  if (target_size <= 3 && original_size <= 3) {
1424  // Storage should stay inline when target size is small.
1425  EXPECT_EQ(3, v.capacity());
1426  }
1427  EXPECT_TRUE(std::equal(v.begin(), v.end(), new_contents.begin(),
1428  InstanceValuesEqual<Instance>));
1429  }
1430  }
1431 }
1432 
1433 TYPED_TEST_P(InstanceTest, RangedAssign) {
1434  using Instance = TypeParam;
1435  // Test with const and non-const, random access and non-random-access sources.
1436  // TODO(bsamwel): Test with an input iterator source.
1437  SCOPED_TRACE("std::list");
1438  InstanceRangedAssignTestForContainer<Instance, std::list<Instance>>();
1439  SCOPED_TRACE("const std::list");
1440  InstanceRangedAssignTestForContainer<Instance, const std::list<Instance>>();
1441  SCOPED_TRACE("std::vector");
1442  InstanceRangedAssignTestForContainer<Instance, std::vector<Instance>>();
1443  SCOPED_TRACE("const std::vector");
1444  InstanceRangedAssignTestForContainer<Instance, const std::vector<Instance>>();
1445 }
1446 
1447 TEST(InitializerListConstructor, SimpleTypeWithInlineBacking) {
1449  AllOf(SizeIs(3), CapacityIs(4), ElementsAre(4, 5, 6)));
1450 }
1451 
1452 TEST(InitializerListConstructor, SimpleTypeWithReallocationRequired) {
1454  AllOf(SizeIs(3), CapacityIs(Gt(2)), ElementsAre(4, 5, 6)));
1455 }
1456 
1457 TEST(InitializerListConstructor, DisparateTypesInList) {
1459 
1461  ElementsAre("foo", "bar"));
1462 }
1463 
1464 TEST(InitializerListConstructor, ComplexTypeWithInlineBacking) {
1466  CopyableMovableInstance(0)}),
1467  AllOf(SizeIs(1), CapacityIs(1), ElementsAre(ValueIs(0))));
1468 }
1469 
1470 TEST(InitializerListConstructor, ComplexTypeWithReallocationRequired) {
1471  EXPECT_THAT(
1473  CopyableMovableInstance(0), CopyableMovableInstance(1)}),
1474  AllOf(SizeIs(2), CapacityIs(Gt(1)), ElementsAre(ValueIs(0), ValueIs(1))));
1475 }
1476 
1477 TEST(InitializerListAssign, SimpleTypeFitsInlineBacking) {
1478  for (size_t original_size = 0; original_size <= 4; ++original_size) {
1479  SCOPED_TRACE(original_size);
1480 
1481  absl::InlinedVector<int, 2> v1(original_size, 12345);
1482  const size_t original_capacity_v1 = v1.capacity();
1483  v1.assign({3});
1484  EXPECT_THAT(
1485  v1, AllOf(SizeIs(1), CapacityIs(original_capacity_v1), ElementsAre(3)));
1486 
1487  absl::InlinedVector<int, 2> v2(original_size, 12345);
1488  const size_t original_capacity_v2 = v2.capacity();
1489  v2 = {3};
1490  EXPECT_THAT(
1491  v2, AllOf(SizeIs(1), CapacityIs(original_capacity_v2), ElementsAre(3)));
1492  }
1493 }
1494 
1495 TEST(InitializerListAssign, SimpleTypeDoesNotFitInlineBacking) {
1496  for (size_t original_size = 0; original_size <= 4; ++original_size) {
1497  SCOPED_TRACE(original_size);
1498  absl::InlinedVector<int, 2> v1(original_size, 12345);
1499  v1.assign({3, 4, 5});
1500  EXPECT_THAT(v1, AllOf(SizeIs(3), ElementsAre(3, 4, 5)));
1501  EXPECT_LE(3, v1.capacity());
1502 
1503  absl::InlinedVector<int, 2> v2(original_size, 12345);
1504  v2 = {3, 4, 5};
1505  EXPECT_THAT(v2, AllOf(SizeIs(3), ElementsAre(3, 4, 5)));
1506  EXPECT_LE(3, v2.capacity());
1507  }
1508 }
1509 
1510 TEST(InitializerListAssign, DisparateTypesInList) {
1512  v_int1.assign({-7, 8ULL});
1513  EXPECT_THAT(v_int1, ElementsAre(-7, 8));
1514 
1516  v_int2 = {-7, 8ULL};
1517  EXPECT_THAT(v_int2, ElementsAre(-7, 8));
1518 
1520  v_string1.assign({"foo", std::string("bar")});
1521  EXPECT_THAT(v_string1, ElementsAre("foo", "bar"));
1522 
1524  v_string2 = {"foo", std::string("bar")};
1525  EXPECT_THAT(v_string2, ElementsAre("foo", "bar"));
1526 }
1527 
1528 TYPED_TEST_P(InstanceTest, InitializerListAssign) {
1529  using Instance = TypeParam;
1530  for (size_t original_size = 0; original_size <= 4; ++original_size) {
1531  SCOPED_TRACE(original_size);
1532  absl::InlinedVector<Instance, 2> v(original_size, Instance(12345));
1533  const size_t original_capacity = v.capacity();
1534  v.assign({Instance(3)});
1535  EXPECT_THAT(v, AllOf(SizeIs(1), CapacityIs(original_capacity),
1536  ElementsAre(ValueIs(3))));
1537  }
1538  for (size_t original_size = 0; original_size <= 4; ++original_size) {
1539  SCOPED_TRACE(original_size);
1540  absl::InlinedVector<Instance, 2> v(original_size, Instance(12345));
1541  v.assign({Instance(3), Instance(4), Instance(5)});
1542  EXPECT_THAT(
1543  v, AllOf(SizeIs(3), ElementsAre(ValueIs(3), ValueIs(4), ValueIs(5))));
1544  EXPECT_LE(3, v.capacity());
1545  }
1546 }
1547 
1548 REGISTER_TYPED_TEST_SUITE_P(InstanceTest, Swap, CountConstructorsDestructors,
1549  CountConstructorsDestructorsOnCopyConstruction,
1550  CountConstructorsDestructorsOnMoveConstruction,
1551  CountConstructorsDestructorsOnAssignment,
1552  CountConstructorsDestructorsOnMoveAssignment,
1553  CountElemAssignInlineBacking, RangedConstructor,
1554  RangedAssign, InitializerListAssign);
1555 
1556 using InstanceTypes =
1558 INSTANTIATE_TYPED_TEST_SUITE_P(InstanceTestOnTypes, InstanceTest,
1559  InstanceTypes);
1560 
1561 TEST(DynamicVec, DynamicVecCompiles) {
1562  DynamicVec v;
1563  (void)v;
1564 }
1565 
1566 TEST(AllocatorSupportTest, Constructors) {
1567  using MyAlloc = CountingAllocator<int>;
1568  using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
1569  const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
1570  int64_t allocated = 0;
1571  MyAlloc alloc(&allocated);
1572  { AllocVec ABSL_ATTRIBUTE_UNUSED v; }
1573  { AllocVec ABSL_ATTRIBUTE_UNUSED v(alloc); }
1574  { AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc); }
1575  { AllocVec ABSL_ATTRIBUTE_UNUSED v({1, 2, 3}, alloc); }
1576 
1577  AllocVec v2;
1578  { AllocVec ABSL_ATTRIBUTE_UNUSED v(v2, alloc); }
1579  { AllocVec ABSL_ATTRIBUTE_UNUSED v(std::move(v2), alloc); }
1580 }
1581 
1582 TEST(AllocatorSupportTest, CountAllocations) {
1583  using MyAlloc = CountingAllocator<int>;
1584  using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
1585  const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
1586  int64_t allocated = 0;
1587  MyAlloc alloc(&allocated);
1588  {
1589  AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + 4, alloc);
1590  EXPECT_THAT(allocated, 0);
1591  }
1592  EXPECT_THAT(allocated, 0);
1593  {
1594  AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc);
1595  EXPECT_THAT(allocated, v.size() * sizeof(int));
1596  }
1597  EXPECT_THAT(allocated, 0);
1598  {
1599  AllocVec v(4, 1, alloc);
1600  EXPECT_THAT(allocated, 0);
1601 
1602  int64_t allocated2 = 0;
1603  MyAlloc alloc2(&allocated2);
1604  AllocVec v2(v, alloc2);
1605  EXPECT_THAT(allocated2, 0);
1606 
1607  int64_t allocated3 = 0;
1608  MyAlloc alloc3(&allocated3);
1609  AllocVec v3(std::move(v), alloc3);
1610  EXPECT_THAT(allocated3, 0);
1611  }
1612  EXPECT_THAT(allocated, 0);
1613  {
1614  AllocVec v(8, 2, alloc);
1615  EXPECT_THAT(allocated, v.size() * sizeof(int));
1616 
1617  int64_t allocated2 = 0;
1618  MyAlloc alloc2(&allocated2);
1619  AllocVec v2(v, alloc2);
1620  EXPECT_THAT(allocated2, v2.size() * sizeof(int));
1621 
1622  int64_t allocated3 = 0;
1623  MyAlloc alloc3(&allocated3);
1624  AllocVec v3(std::move(v), alloc3);
1625  EXPECT_THAT(allocated3, v3.size() * sizeof(int));
1626  }
1627  EXPECT_EQ(allocated, 0);
1628  {
1629  // Test shrink_to_fit deallocations.
1630  AllocVec v(8, 2, alloc);
1631  EXPECT_EQ(allocated, 8 * sizeof(int));
1632  v.resize(5);
1633  EXPECT_EQ(allocated, 8 * sizeof(int));
1634  v.shrink_to_fit();
1635  EXPECT_EQ(allocated, 5 * sizeof(int));
1636  v.resize(4);
1637  EXPECT_EQ(allocated, 5 * sizeof(int));
1638  v.shrink_to_fit();
1639  EXPECT_EQ(allocated, 0);
1640  }
1641 }
1642 
1643 TEST(AllocatorSupportTest, SwapBothAllocated) {
1644  using MyAlloc = CountingAllocator<int>;
1645  using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
1646  int64_t allocated1 = 0;
1647  int64_t allocated2 = 0;
1648  {
1649  const int ia1[] = {0, 1, 2, 3, 4, 5, 6, 7};
1650  const int ia2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1651  MyAlloc a1(&allocated1);
1652  MyAlloc a2(&allocated2);
1653  AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1);
1654  AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2);
1655  EXPECT_LT(v1.capacity(), v2.capacity());
1656  EXPECT_THAT(allocated1, v1.capacity() * sizeof(int));
1657  EXPECT_THAT(allocated2, v2.capacity() * sizeof(int));
1658  v1.swap(v2);
1659  EXPECT_THAT(v1, ElementsAreArray(ia2));
1660  EXPECT_THAT(v2, ElementsAreArray(ia1));
1661  EXPECT_THAT(allocated1, v2.capacity() * sizeof(int));
1662  EXPECT_THAT(allocated2, v1.capacity() * sizeof(int));
1663  }
1664  EXPECT_THAT(allocated1, 0);
1665  EXPECT_THAT(allocated2, 0);
1666 }
1667 
1668 TEST(AllocatorSupportTest, SwapOneAllocated) {
1669  using MyAlloc = CountingAllocator<int>;
1670  using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
1671  int64_t allocated1 = 0;
1672  int64_t allocated2 = 0;
1673  {
1674  const int ia1[] = {0, 1, 2, 3, 4, 5, 6, 7};
1675  const int ia2[] = {0, 1, 2, 3};
1676  MyAlloc a1(&allocated1);
1677  MyAlloc a2(&allocated2);
1678  AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1);
1679  AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2);
1680  EXPECT_THAT(allocated1, v1.capacity() * sizeof(int));
1681  EXPECT_THAT(allocated2, 0);
1682  v1.swap(v2);
1683  EXPECT_THAT(v1, ElementsAreArray(ia2));
1684  EXPECT_THAT(v2, ElementsAreArray(ia1));
1685  EXPECT_THAT(allocated1, v2.capacity() * sizeof(int));
1686  EXPECT_THAT(allocated2, 0);
1687  EXPECT_TRUE(v2.get_allocator() == a1);
1688  EXPECT_TRUE(v1.get_allocator() == a2);
1689  }
1690  EXPECT_THAT(allocated1, 0);
1691  EXPECT_THAT(allocated2, 0);
1692 }
1693 
1694 TEST(AllocatorSupportTest, ScopedAllocatorWorksInlined) {
1695  using StdVector = std::vector<int, CountingAllocator<int>>;
1696  using Alloc = CountingAllocator<StdVector>;
1697  using ScopedAlloc = std::scoped_allocator_adaptor<Alloc>;
1699 
1700  int64_t total_allocated_byte_count = 0;
1701 
1702  AllocVec inlined_case(ScopedAlloc(Alloc(+&total_allocated_byte_count)));
1703 
1704  // Called only once to remain inlined
1705  inlined_case.emplace_back();
1706 
1707  int64_t absl_responsible_for_count = total_allocated_byte_count;
1708 
1709  // MSVC's allocator preemptively allocates in debug mode
1710 #if !defined(_MSC_VER)
1711  EXPECT_EQ(absl_responsible_for_count, 0);
1712 #endif // !defined(_MSC_VER)
1713 
1714  inlined_case[0].emplace_back();
1715  EXPECT_GT(total_allocated_byte_count, absl_responsible_for_count);
1716 
1717  inlined_case.clear();
1718  inlined_case.shrink_to_fit();
1719  EXPECT_EQ(total_allocated_byte_count, 0);
1720 }
1721 
1722 TEST(AllocatorSupportTest, ScopedAllocatorWorksAllocated) {
1723  using StdVector = std::vector<int, CountingAllocator<int>>;
1724  using Alloc = CountingAllocator<StdVector>;
1725  using ScopedAlloc = std::scoped_allocator_adaptor<Alloc>;
1727 
1728  int64_t total_allocated_byte_count = 0;
1729 
1730  AllocVec allocated_case(ScopedAlloc(Alloc(+&total_allocated_byte_count)));
1731 
1732  // Called twice to force into being allocated
1733  allocated_case.emplace_back();
1734  allocated_case.emplace_back();
1735 
1736  int64_t absl_responsible_for_count = total_allocated_byte_count;
1737  EXPECT_GT(absl_responsible_for_count, 0);
1738 
1739  allocated_case[1].emplace_back();
1740  EXPECT_GT(total_allocated_byte_count, absl_responsible_for_count);
1741 
1742  allocated_case.clear();
1743  allocated_case.shrink_to_fit();
1744  EXPECT_EQ(total_allocated_byte_count, 0);
1745 }
1746 
1747 TEST(AllocatorSupportTest, SizeAllocConstructor) {
1748  constexpr int inlined_size = 4;
1749  using Alloc = CountingAllocator<int>;
1751 
1752  {
1753  auto len = inlined_size / 2;
1754  int64_t allocated = 0;
1755  auto v = AllocVec(len, Alloc(&allocated));
1756 
1757  // Inline storage used; allocator should not be invoked
1758  EXPECT_THAT(allocated, 0);
1759  EXPECT_THAT(v, AllOf(SizeIs(len), Each(0)));
1760  }
1761 
1762  {
1763  auto len = inlined_size * 2;
1764  int64_t allocated = 0;
1765  auto v = AllocVec(len, Alloc(&allocated));
1766 
1767  // Out of line storage used; allocation of 8 elements expected
1768  EXPECT_THAT(allocated, len * sizeof(int));
1769  EXPECT_THAT(v, AllOf(SizeIs(len), Each(0)));
1770  }
1771 }
1772 
1773 TEST(InlinedVectorTest, MinimumAllocatorCompilesUsingTraits) {
1774  using T = int;
1775  using A = std::allocator<T>;
1776  using ATraits = absl::allocator_traits<A>;
1777 
1778  struct MinimumAllocator {
1779  using value_type = T;
1780 
1781  value_type* allocate(size_t n) {
1782  A a;
1783  return ATraits::allocate(a, n);
1784  }
1785 
1786  void deallocate(value_type* p, size_t n) {
1787  A a;
1788  ATraits::deallocate(a, p, n);
1789  }
1790  };
1791 
1793  vec.emplace_back();
1794  vec.resize(0);
1795 }
1796 
1797 TEST(InlinedVectorTest, AbslHashValueWorks) {
1798  using V = absl::InlinedVector<int, 4>;
1799  std::vector<V> cases;
1800 
1801  // Generate a variety of vectors some of these are small enough for the inline
1802  // space but are stored out of line.
1803  for (int i = 0; i < 10; ++i) {
1804  V v;
1805  for (int j = 0; j < i; ++j) {
1806  v.push_back(j);
1807  }
1808  cases.push_back(v);
1809  v.resize(i % 4);
1810  cases.push_back(v);
1811  }
1812 
1814 }
1815 
1816 } // anonymous namespace
TYPED_TEST_P
#define TYPED_TEST_P(SuiteName, TestName)
Definition: googletest/googletest/include/gtest/gtest-typed-test.h:270
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
ABSL_RAW_CHECK
#define ABSL_RAW_CHECK(condition, message)
Definition: abseil-cpp/absl/base/internal/raw_logging.h:59
absl::swap_internal::Swap
void Swap(T &lhs, T &rhs) noexcept(IsNothrowSwappable< T >::value)
Definition: abseil-cpp/absl/meta/type_traits.h:772
regen-readme.it
it
Definition: regen-readme.py:15
testing::Gt
internal::GtMatcher< Rhs > Gt(Rhs x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8591
ABSL_BASE_INTERNAL_EXPECT_FAIL
#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text)
Definition: abseil-cpp/absl/base/internal/exception_testing.h:37
absl::str_format_internal::LengthMod::j
@ j
absl::VerifyTypeImplementsAbslHashCorrectly
ABSL_NAMESPACE_BEGIN ABSL_MUST_USE_RESULT testing::AssertionResult VerifyTypeImplementsAbslHashCorrectly(const Container &values)
Definition: abseil-cpp/absl/hash/hash_testing.h:345
grpc_event_engine::experimental::slice_detail::operator==
bool operator==(const BaseSlice &a, const BaseSlice &b)
Definition: include/grpc/event_engine/slice.h:117
pos
int pos
Definition: libuv/docs/code/tty-gravity/main.c:11
absl::InlinedVector::emplace_back
reference emplace_back(Args &&... args)
Definition: abseil-cpp/absl/container/inlined_vector.h:675
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
ABSL_ATTRIBUTE_UNUSED
#define ABSL_ATTRIBUTE_UNUSED
Definition: abseil-cpp/absl/base/attributes.h:550
p_
std::unique_ptr< unsigned char[]> p_
Definition: abseil-cpp/absl/container/internal/layout_test.cc:1627
copy
static int copy(grpc_slice_buffer *input, grpc_slice_buffer *output)
Definition: message_compress.cc:145
EXPECT_GT
#define EXPECT_GT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2036
absl::str_format_internal::AllOf
constexpr bool AllOf()
Definition: abseil-cpp/absl/strings/internal/str_format/checker.h:39
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
arg::value
void * value
Definition: cmdline.cc:44
absl::InlinedVector::resize
void resize(size_type n)
Definition: abseil-cpp/absl/container/inlined_vector.h:550
absl::FormatConversionChar::s
@ s
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
absl::test_internal::CopyableOnlyInstance
Definition: abseil-cpp/absl/container/internal/test_instance_tracker.h:226
EXPECT_LE
#define EXPECT_LE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2030
xds_manager.p
p
Definition: xds_manager.py:60
absl::allocator_traits
Definition: third_party/abseil-cpp/absl/memory/memory.h:427
second
StrT second
Definition: cxa_demangle.cpp:4885
env.new
def new
Definition: env.py:51
ABSL_ARRAYSIZE
#define ABSL_ARRAYSIZE(array)
Definition: abseil-cpp/absl/base/macros.h:44
iterator
const typedef MCPhysReg * iterator
Definition: MCRegisterInfo.h:27
setup.k
k
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
T
#define T(upbtypeconst, upbtype, ctype, default_value)
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
testing::ElementsAreArray
internal::ElementsAreArrayMatcher< typename ::std::iterator_traits< Iter >::value_type > ElementsAreArray(Iter first, Iter last)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8465
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
testing::ElementsAre
internal::ElementsAreMatcher< ::testing::tuple<> > ElementsAre()
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:13040
testing::internal::ProxyTypeList
Definition: googletest/googletest/include/gtest/internal/gtest-type-util.h:155
ULL
#define ULL(x)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:57
absl::InlinedVector::back
reference back()
Definition: abseil-cpp/absl/container/inlined_vector.h:377
absl::FormatConversionChar::e
@ e
absl::InlinedVector::begin
iterator begin() noexcept
Definition: abseil-cpp/absl/container/inlined_vector.h:392
SCOPED_TRACE
#define SCOPED_TRACE(message)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2264
a2
T::first_type a2
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:307
xds_interop_client.int
int
Definition: xds_interop_client.py:113
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
swap
#define swap(a, b)
Definition: qsort.h:111
TEST
#define TEST(name, init_size,...)
Definition: arena_test.cc:75
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
testing::Eq
internal::EqMatcher< T > Eq(T x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8561
absl::InlinedVector::push_back
void push_back(const_reference v)
Definition: abseil-cpp/absl/container/inlined_vector.h:682
counter
static int counter
Definition: abseil-cpp/absl/flags/reflection_test.cc:131
arg
Definition: cmdline.cc:40
absl::compare_internal::value_type
int8_t value_type
Definition: abseil-cpp/absl/types/compare.h:45
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:1226
testing::SizeIs
internal::SizeIsMatcher< SizeMatcher > SizeIs(const SizeMatcher &size_matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8947
INSTANTIATE_TYPED_TEST_SUITE_P
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types,...)
Definition: googletest/googletest/include/gtest/gtest-typed-test.h:306
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
REGISTER_TYPED_TEST_SUITE_P
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName,...)
Definition: googletest/googletest/include/gtest/gtest-typed-test.h:289
absl::flags_internal::Alloc
void * Alloc(FlagOpFn op)
Definition: abseil-cpp/absl/flags/internal/flag.h:102
absl::InlinedVector::size
size_type size() const noexcept
Definition: abseil-cpp/absl/container/inlined_vector.h:270
a1
T::first_type a1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:305
min
#define min(a, b)
Definition: qsort.h:83
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
absl::InlinedVector::insert
iterator insert(const_iterator pos, const_reference v)
Definition: abseil-cpp/absl/container/inlined_vector.h:569
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
EXPECT_DEATH_IF_SUPPORTED
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-death-test.h:335
value_
int value_
Definition: orphanable_test.cc:38
value
const char * value
Definition: hpack_parser_table.cc:165
TYPED_TEST_SUITE_P
#define TYPED_TEST_SUITE_P(SuiteName)
Definition: googletest/googletest/include/gtest/gtest-typed-test.h:259
count_
int * count_
Definition: connectivity_state_test.cc:65
absl::inlined_vector_internal::ReverseIterator
typename std::reverse_iterator< Iterator< A > > ReverseIterator
Definition: abseil-cpp/absl/container/internal/inlined_vector.h:68
absl::container_internal::CountingAllocator
Definition: abseil-cpp/absl/container/internal/counting_allocator.h:33
cv
unsigned cv
Definition: cxa_demangle.cpp:4908
google::protobuf.internal.python_message.Clear
Clear
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:1430
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
testing::ExplainMatchResult
bool ExplainMatchResult(M matcher, const T &value, MatchResultListener *listener)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:9173
first
StrT first
Definition: cxa_demangle.cpp:4884
EXPECT_LT
#define EXPECT_LT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2032
MATCHER_P
#define MATCHER_P(name, p0, description)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-generated-matchers.h:311
A
Definition: miscompile_with_no_unique_address_test.cc:23
absl::InlinedVector::assign
void assign(size_type n, const_reference v)
Definition: abseil-cpp/absl/container/inlined_vector.h:507
EXPECT_GE
#define EXPECT_GE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2034
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
absl::test_internal::CopyableMovableInstance
Definition: abseil-cpp/absl/container/internal/test_instance_tracker.h:240
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
absl::test_internal::InstanceTracker
Definition: abseil-cpp/absl/container/internal/test_instance_tracker.h:160
testing::AllOf
internal::AllOfResult2< M1, M2 >::type AllOf(M1 m1, M2 m2)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:13472
tracker
SessionTracker * tracker
Definition: ssl_session_cache_test.cc:38
iter
Definition: test_winkernel.cpp:47
google::protobuf::python::repeated_composite_container::Insert
static PyObject * Insert(PyObject *pself, PyObject *args)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/repeated_composite_container.cc:139
absl::InlinedVector
Definition: abseil-cpp/absl/container/inlined_vector.h:69
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
testing::Each
internal::EachMatcher< M > Each(M matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:9133
testing::Ref
internal::RefMatcher< T & > Ref(T &x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8628
regress.m
m
Definition: regress/regress.py:25
absl::InlinedVector::emplace
iterator emplace(const_iterator pos, Args &&... args)
Definition: abseil-cpp/absl/container/inlined_vector.h:659
absl::InlinedVector::end
iterator end() noexcept
Definition: abseil-cpp/absl/container/inlined_vector.h:401
alloc
std::allocator< int > alloc
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:87
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
testing::PrintToString
::std::string PrintToString(const T &value)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-printers.h:915


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:05