abseil-cpp/absl/container/fixed_array_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/fixed_array.h"
16 
17 #include <stdio.h>
18 
19 #include <cstring>
20 #include <list>
21 #include <memory>
22 #include <numeric>
23 #include <scoped_allocator>
24 #include <stdexcept>
25 #include <string>
26 #include <vector>
27 
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 #include "absl/base/config.h"
31 #include "absl/base/internal/exception_testing.h"
32 #include "absl/base/options.h"
33 #include "absl/container/internal/counting_allocator.h"
34 #include "absl/hash/hash_testing.h"
35 #include "absl/memory/memory.h"
36 
38 
39 namespace {
40 
41 // Helper routine to determine if a absl::FixedArray used stack allocation.
42 template <typename ArrayType>
43 static bool IsOnStack(const ArrayType& a) {
44  return a.size() <= ArrayType::inline_elements;
45 }
46 
47 class ConstructionTester {
48  public:
49  ConstructionTester() : self_ptr_(this), value_(0) { constructions++; }
50  ~ConstructionTester() {
51  assert(self_ptr_ == this);
52  self_ptr_ = nullptr;
53  destructions++;
54  }
55 
56  // These are incremented as elements are constructed and destructed so we can
57  // be sure all elements are properly cleaned up.
58  static int constructions;
59  static int destructions;
60 
61  void CheckConstructed() { assert(self_ptr_ == this); }
62 
63  void set(int value) { value_ = value; }
64  int get() { return value_; }
65 
66  private:
67  // self_ptr_ should always point to 'this' -- that's how we can be sure the
68  // constructor has been called.
69  ConstructionTester* self_ptr_;
70  int value_;
71 };
72 
73 int ConstructionTester::constructions = 0;
74 int ConstructionTester::destructions = 0;
75 
76 // ThreeInts will initialize its three ints to the value stored in
77 // ThreeInts::counter. The constructor increments counter so that each object
78 // in an array of ThreeInts will have different values.
79 class ThreeInts {
80  public:
81  ThreeInts() {
82  x_ = counter;
83  y_ = counter;
84  z_ = counter;
85  ++counter;
86  }
87 
88  static int counter;
89 
90  int x_, y_, z_;
91 };
92 
93 int ThreeInts::counter = 0;
94 
95 TEST(FixedArrayTest, CopyCtor) {
96  absl::FixedArray<int, 10> on_stack(5);
97  std::iota(on_stack.begin(), on_stack.end(), 0);
98  absl::FixedArray<int, 10> stack_copy = on_stack;
99  EXPECT_THAT(stack_copy, ElementsAreArray(on_stack));
100  EXPECT_TRUE(IsOnStack(stack_copy));
101 
102  absl::FixedArray<int, 10> allocated(15);
103  std::iota(allocated.begin(), allocated.end(), 0);
104  absl::FixedArray<int, 10> alloced_copy = allocated;
105  EXPECT_THAT(alloced_copy, ElementsAreArray(allocated));
106  EXPECT_FALSE(IsOnStack(alloced_copy));
107 }
108 
109 TEST(FixedArrayTest, MoveCtor) {
110  absl::FixedArray<std::unique_ptr<int>, 10> on_stack(5);
111  for (int i = 0; i < 5; ++i) {
112  on_stack[i] = absl::make_unique<int>(i);
113  }
114 
115  absl::FixedArray<std::unique_ptr<int>, 10> stack_copy = std::move(on_stack);
116  for (int i = 0; i < 5; ++i) EXPECT_EQ(*(stack_copy[i]), i);
117  EXPECT_EQ(stack_copy.size(), on_stack.size());
118 
119  absl::FixedArray<std::unique_ptr<int>, 10> allocated(15);
120  for (int i = 0; i < 15; ++i) {
121  allocated[i] = absl::make_unique<int>(i);
122  }
123 
124  absl::FixedArray<std::unique_ptr<int>, 10> alloced_copy =
125  std::move(allocated);
126  for (int i = 0; i < 15; ++i) EXPECT_EQ(*(alloced_copy[i]), i);
127  EXPECT_EQ(allocated.size(), alloced_copy.size());
128 }
129 
130 TEST(FixedArrayTest, SmallObjects) {
131  // Small object arrays
132  {
133  // Short arrays should be on the stack
135  EXPECT_TRUE(IsOnStack(array));
136  }
137 
138  {
139  // Large arrays should be on the heap
140  absl::FixedArray<int> array(1048576);
141  EXPECT_FALSE(IsOnStack(array));
142  }
143 
144  {
145  // Arrays of <= default size should be on the stack
147  EXPECT_TRUE(IsOnStack(array));
148  }
149 
150  {
151  // Arrays of > default size should be on the heap
153  EXPECT_FALSE(IsOnStack(array));
154  }
155 
156  {
157  // Arrays with different size elements should use approximately
158  // same amount of stack space
159  absl::FixedArray<int> array1(0);
160  absl::FixedArray<char> array2(0);
161  EXPECT_LE(sizeof(array1), sizeof(array2) + 100);
162  EXPECT_LE(sizeof(array2), sizeof(array1) + 100);
163  }
164 
165  {
166  // Ensure that vectors are properly constructed inside a fixed array.
168  EXPECT_EQ(0, array[0].size());
169  EXPECT_EQ(0, array[1].size());
170  }
171 
172  {
173  // Regardless of absl::FixedArray implementation, check that a type with a
174  // low alignment requirement and a non power-of-two size is initialized
175  // correctly.
176  ThreeInts::counter = 1;
178  EXPECT_EQ(1, array[0].x_);
179  EXPECT_EQ(1, array[0].y_);
180  EXPECT_EQ(1, array[0].z_);
181  EXPECT_EQ(2, array[1].x_);
182  EXPECT_EQ(2, array[1].y_);
183  EXPECT_EQ(2, array[1].z_);
184  }
185 }
186 
187 TEST(FixedArrayTest, AtThrows) {
188  absl::FixedArray<int> a = {1, 2, 3};
189  EXPECT_EQ(a.at(2), 3);
190  ABSL_BASE_INTERNAL_EXPECT_FAIL(a.at(3), std::out_of_range,
191  "failed bounds check");
192 }
193 
194 TEST(FixedArrayTest, Hardened) {
195 #if !defined(NDEBUG) || ABSL_OPTION_HARDENED
196  absl::FixedArray<int> a = {1, 2, 3};
197  EXPECT_EQ(a[2], 3);
199  EXPECT_DEATH_IF_SUPPORTED(a[-1], "");
200 
204  EXPECT_DEATH_IF_SUPPORTED(empty.front(), "");
205  EXPECT_DEATH_IF_SUPPORTED(empty.back(), "");
206 #endif
207 }
208 
209 TEST(FixedArrayRelationalsTest, EqualArrays) {
210  for (int i = 0; i < 10; ++i) {
212  std::iota(a1.begin(), a1.end(), 0);
213  absl::FixedArray<int, 5> a2(a1.begin(), a1.end());
214 
215  EXPECT_TRUE(a1 == a2);
216  EXPECT_FALSE(a1 != a2);
217  EXPECT_TRUE(a2 == a1);
218  EXPECT_FALSE(a2 != a1);
219  EXPECT_FALSE(a1 < a2);
220  EXPECT_FALSE(a1 > a2);
221  EXPECT_FALSE(a2 < a1);
222  EXPECT_FALSE(a2 > a1);
223  EXPECT_TRUE(a1 <= a2);
224  EXPECT_TRUE(a1 >= a2);
225  EXPECT_TRUE(a2 <= a1);
226  EXPECT_TRUE(a2 >= a1);
227  }
228 }
229 
230 TEST(FixedArrayRelationalsTest, UnequalArrays) {
231  for (int i = 1; i < 10; ++i) {
233  std::iota(a1.begin(), a1.end(), 0);
234  absl::FixedArray<int, 5> a2(a1.begin(), a1.end());
235  --a2[i / 2];
236 
237  EXPECT_FALSE(a1 == a2);
238  EXPECT_TRUE(a1 != a2);
239  EXPECT_FALSE(a2 == a1);
240  EXPECT_TRUE(a2 != a1);
241  EXPECT_FALSE(a1 < a2);
242  EXPECT_TRUE(a1 > a2);
243  EXPECT_TRUE(a2 < a1);
244  EXPECT_FALSE(a2 > a1);
245  EXPECT_FALSE(a1 <= a2);
246  EXPECT_TRUE(a1 >= a2);
247  EXPECT_TRUE(a2 <= a1);
248  EXPECT_FALSE(a2 >= a1);
249  }
250 }
251 
252 template <int stack_elements>
253 static void TestArray(int n) {
254  SCOPED_TRACE(n);
255  SCOPED_TRACE(stack_elements);
256  ConstructionTester::constructions = 0;
257  ConstructionTester::destructions = 0;
258  {
260 
261  EXPECT_THAT(array.size(), n);
262  EXPECT_THAT(array.memsize(), sizeof(ConstructionTester) * n);
263  EXPECT_THAT(array.begin() + n, array.end());
264 
265  // Check that all elements were constructed
266  for (int i = 0; i < n; i++) {
267  array[i].CheckConstructed();
268  }
269  // Check that no other elements were constructed
270  EXPECT_THAT(ConstructionTester::constructions, n);
271 
272  // Test operator[]
273  for (int i = 0; i < n; i++) {
274  array[i].set(i);
275  }
276  for (int i = 0; i < n; i++) {
277  EXPECT_THAT(array[i].get(), i);
278  EXPECT_THAT(array.data()[i].get(), i);
279  }
280 
281  // Test data()
282  for (int i = 0; i < n; i++) {
283  array.data()[i].set(i + 1);
284  }
285  for (int i = 0; i < n; i++) {
286  EXPECT_THAT(array[i].get(), i + 1);
287  EXPECT_THAT(array.data()[i].get(), i + 1);
288  }
289  } // Close scope containing 'array'.
290 
291  // Check that all constructed elements were destructed.
292  EXPECT_EQ(ConstructionTester::constructions,
293  ConstructionTester::destructions);
294 }
295 
296 template <int elements_per_inner_array, int inline_elements>
297 static void TestArrayOfArrays(int n) {
298  SCOPED_TRACE(n);
299  SCOPED_TRACE(inline_elements);
300  SCOPED_TRACE(elements_per_inner_array);
301  ConstructionTester::constructions = 0;
302  ConstructionTester::destructions = 0;
303  {
304  using InnerArray = ConstructionTester[elements_per_inner_array];
305  // Heap-allocate the FixedArray to avoid blowing the stack frame.
306  auto array_ptr =
307  absl::make_unique<absl::FixedArray<InnerArray, inline_elements>>(n);
308  auto& array = *array_ptr;
309 
310  ASSERT_EQ(array.size(), n);
311  ASSERT_EQ(array.memsize(),
312  sizeof(ConstructionTester) * elements_per_inner_array * n);
313  ASSERT_EQ(array.begin() + n, array.end());
314 
315  // Check that all elements were constructed
316  for (int i = 0; i < n; i++) {
317  for (int j = 0; j < elements_per_inner_array; j++) {
318  (array[i])[j].CheckConstructed();
319  }
320  }
321  // Check that no other elements were constructed
322  ASSERT_EQ(ConstructionTester::constructions, n * elements_per_inner_array);
323 
324  // Test operator[]
325  for (int i = 0; i < n; i++) {
326  for (int j = 0; j < elements_per_inner_array; j++) {
327  (array[i])[j].set(i * elements_per_inner_array + j);
328  }
329  }
330  for (int i = 0; i < n; i++) {
331  for (int j = 0; j < elements_per_inner_array; j++) {
332  ASSERT_EQ((array[i])[j].get(), i * elements_per_inner_array + j);
333  ASSERT_EQ((array.data()[i])[j].get(), i * elements_per_inner_array + j);
334  }
335  }
336 
337  // Test data()
338  for (int i = 0; i < n; i++) {
339  for (int j = 0; j < elements_per_inner_array; j++) {
340  (array.data()[i])[j].set((i + 1) * elements_per_inner_array + j);
341  }
342  }
343  for (int i = 0; i < n; i++) {
344  for (int j = 0; j < elements_per_inner_array; j++) {
345  ASSERT_EQ((array[i])[j].get(), (i + 1) * elements_per_inner_array + j);
346  ASSERT_EQ((array.data()[i])[j].get(),
347  (i + 1) * elements_per_inner_array + j);
348  }
349  }
350  } // Close scope containing 'array'.
351 
352  // Check that all constructed elements were destructed.
353  EXPECT_EQ(ConstructionTester::constructions,
354  ConstructionTester::destructions);
355 }
356 
357 TEST(IteratorConstructorTest, NonInline) {
358  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
362  for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
363  ASSERT_EQ(kInput[i], fixed[i]);
364  }
365 }
366 
367 TEST(IteratorConstructorTest, Inline) {
368  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
372  for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
373  ASSERT_EQ(kInput[i], fixed[i]);
374  }
375 }
376 
377 TEST(IteratorConstructorTest, NonPod) {
378  char const* kInput[] = {"red", "orange", "yellow", "green",
379  "blue", "indigo", "violet"};
383  for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
384  ASSERT_EQ(kInput[i], fixed[i]);
385  }
386 }
387 
388 TEST(IteratorConstructorTest, FromEmptyVector) {
389  std::vector<int> const empty;
390  absl::FixedArray<int> const fixed(empty.begin(), empty.end());
391  EXPECT_EQ(0, fixed.size());
392  EXPECT_EQ(empty.size(), fixed.size());
393 }
394 
395 TEST(IteratorConstructorTest, FromNonEmptyVector) {
396  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
397  std::vector<int> const items(kInput, kInput + ABSL_ARRAYSIZE(kInput));
398  absl::FixedArray<int> const fixed(items.begin(), items.end());
399  ASSERT_EQ(items.size(), fixed.size());
400  for (size_t i = 0; i < items.size(); ++i) {
401  ASSERT_EQ(items[i], fixed[i]);
402  }
403 }
404 
405 TEST(IteratorConstructorTest, FromBidirectionalIteratorRange) {
406  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
407  std::list<int> const items(kInput, kInput + ABSL_ARRAYSIZE(kInput));
408  absl::FixedArray<int> const fixed(items.begin(), items.end());
410 }
411 
412 TEST(InitListConstructorTest, InitListConstruction) {
413  absl::FixedArray<int> fixed = {1, 2, 3};
415 }
416 
417 TEST(FillConstructorTest, NonEmptyArrays) {
418  absl::FixedArray<int> stack_array(4, 1);
419  EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1}));
420 
421  absl::FixedArray<int, 0> heap_array(4, 1);
422  EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1}));
423 }
424 
425 TEST(FillConstructorTest, EmptyArray) {
426  absl::FixedArray<int> empty_fill(0, 1);
427  absl::FixedArray<int> empty_size(0);
428  EXPECT_EQ(empty_fill, empty_size);
429 }
430 
431 TEST(FillConstructorTest, NotTriviallyCopyable) {
432  std::string str = "abcd";
434 
436  EXPECT_EQ(array, strings);
437 }
438 
439 TEST(FillConstructorTest, Disambiguation) {
442 }
443 
444 TEST(FixedArrayTest, ManySizedArrays) {
445  std::vector<int> sizes;
446  for (int i = 1; i < 100; i++) sizes.push_back(i);
447  for (int i = 100; i <= 1000; i += 100) sizes.push_back(i);
448  for (int n : sizes) {
449  TestArray<0>(n);
450  TestArray<1>(n);
451  TestArray<64>(n);
452  TestArray<1000>(n);
453  }
454 }
455 
456 TEST(FixedArrayTest, ManySizedArraysOfArraysOf1) {
457  for (int n = 1; n < 1000; n++) {
458  ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 0>(n)));
459  ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1>(n)));
460  ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 64>(n)));
461  ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1000>(n)));
462  }
463 }
464 
465 TEST(FixedArrayTest, ManySizedArraysOfArraysOf2) {
466  for (int n = 1; n < 1000; n++) {
467  TestArrayOfArrays<2, 0>(n);
468  TestArrayOfArrays<2, 1>(n);
469  TestArrayOfArrays<2, 64>(n);
470  TestArrayOfArrays<2, 1000>(n);
471  }
472 }
473 
474 // If value_type is put inside of a struct container,
475 // we might evoke this error in a hardened build unless data() is carefully
476 // written, so check on that.
477 // error: call to int __builtin___sprintf_chk(etc...)
478 // will always overflow destination buffer [-Werror]
479 TEST(FixedArrayTest, AvoidParanoidDiagnostics) {
481  sprintf(buf.data(), "foo"); // NOLINT(runtime/printf)
482 }
483 
484 TEST(FixedArrayTest, TooBigInlinedSpace) {
485  struct TooBig {
486  char c[1 << 20];
487  }; // too big for even one on the stack
488 
489  // Simulate the data members of absl::FixedArray, a pointer and a size_t.
490  struct Data {
491  TooBig* p;
492  size_t size;
493  };
494 
495  // Make sure TooBig objects are not inlined for 0 or default size.
496  static_assert(sizeof(absl::FixedArray<TooBig, 0>) == sizeof(Data),
497  "0-sized absl::FixedArray should have same size as Data.");
498  static_assert(alignof(absl::FixedArray<TooBig, 0>) == alignof(Data),
499  "0-sized absl::FixedArray should have same alignment as Data.");
500  static_assert(sizeof(absl::FixedArray<TooBig>) == sizeof(Data),
501  "default-sized absl::FixedArray should have same size as Data");
502  static_assert(
503  alignof(absl::FixedArray<TooBig>) == alignof(Data),
504  "default-sized absl::FixedArray should have same alignment as Data.");
505 }
506 
507 // PickyDelete EXPECTs its class-scope deallocation funcs are unused.
508 struct PickyDelete {
509  PickyDelete() {}
510  ~PickyDelete() {}
511  void operator delete(void* p) {
512  EXPECT_TRUE(false) << __FUNCTION__;
513  ::operator delete(p);
514  }
515  void operator delete[](void* p) {
516  EXPECT_TRUE(false) << __FUNCTION__;
517  ::operator delete[](p);
518  }
519 };
520 
521 TEST(FixedArrayTest, UsesGlobalAlloc) { absl::FixedArray<PickyDelete, 0> a(5); }
522 
523 TEST(FixedArrayTest, Data) {
524  static const int kInput[] = {2, 3, 5, 7, 11, 13, 17};
526  EXPECT_EQ(fa.data(), &*fa.begin());
527  EXPECT_EQ(fa.data(), &fa[0]);
528 
529  const absl::FixedArray<int>& cfa = fa;
530  EXPECT_EQ(cfa.data(), &*cfa.begin());
531  EXPECT_EQ(cfa.data(), &cfa[0]);
532 }
533 
534 TEST(FixedArrayTest, Empty) {
536  absl::FixedArray<int> inline_filled(1);
537  absl::FixedArray<int, 0> heap_filled(1);
538  EXPECT_TRUE(empty.empty());
539  EXPECT_FALSE(inline_filled.empty());
540  EXPECT_FALSE(heap_filled.empty());
541 }
542 
543 TEST(FixedArrayTest, FrontAndBack) {
544  absl::FixedArray<int, 3 * sizeof(int)> inlined = {1, 2, 3};
545  EXPECT_EQ(inlined.front(), 1);
546  EXPECT_EQ(inlined.back(), 3);
547 
548  absl::FixedArray<int, 0> allocated = {1, 2, 3};
549  EXPECT_EQ(allocated.front(), 1);
550  EXPECT_EQ(allocated.back(), 3);
551 
552  absl::FixedArray<int> one_element = {1};
553  EXPECT_EQ(one_element.front(), one_element.back());
554 }
555 
556 TEST(FixedArrayTest, ReverseIteratorInlined) {
557  absl::FixedArray<int, 5 * sizeof(int)> a = {0, 1, 2, 3, 4};
558 
559  int counter = 5;
561  iter != a.rend(); ++iter) {
562  counter--;
564  }
565  EXPECT_EQ(counter, 0);
566 
567  counter = 5;
569  iter != a.rend(); ++iter) {
570  counter--;
572  }
573  EXPECT_EQ(counter, 0);
574 
575  counter = 5;
576  for (auto iter = a.crbegin(); iter != a.crend(); ++iter) {
577  counter--;
579  }
580  EXPECT_EQ(counter, 0);
581 }
582 
583 TEST(FixedArrayTest, ReverseIteratorAllocated) {
584  absl::FixedArray<int, 0> a = {0, 1, 2, 3, 4};
585 
586  int counter = 5;
588  iter != a.rend(); ++iter) {
589  counter--;
591  }
592  EXPECT_EQ(counter, 0);
593 
594  counter = 5;
596  iter != a.rend(); ++iter) {
597  counter--;
599  }
600  EXPECT_EQ(counter, 0);
601 
602  counter = 5;
603  for (auto iter = a.crbegin(); iter != a.crend(); ++iter) {
604  counter--;
606  }
607  EXPECT_EQ(counter, 0);
608 }
609 
610 TEST(FixedArrayTest, Fill) {
611  absl::FixedArray<int, 5 * sizeof(int)> inlined(5);
612  int fill_val = 42;
613  inlined.fill(fill_val);
614  for (int i : inlined) EXPECT_EQ(i, fill_val);
615 
616  absl::FixedArray<int, 0> allocated(5);
617  allocated.fill(fill_val);
618  for (int i : allocated) EXPECT_EQ(i, fill_val);
619 
620  // It doesn't do anything, just make sure this compiles.
622  empty.fill(fill_val);
623 }
624 
625 #ifndef __GNUC__
626 TEST(FixedArrayTest, DefaultCtorDoesNotValueInit) {
627  using T = char;
628  constexpr auto capacity = 10;
629  using FixedArrType = absl::FixedArray<T, capacity>;
630  constexpr auto scrubbed_bits = 0x95;
631  constexpr auto length = capacity / 2;
632 
633  alignas(FixedArrType) unsigned char buff[sizeof(FixedArrType)];
634  std::memset(std::addressof(buff), scrubbed_bits, sizeof(FixedArrType));
635 
636  FixedArrType* arr =
637  ::new (static_cast<void*>(std::addressof(buff))) FixedArrType(length);
638  EXPECT_THAT(*arr, testing::Each(scrubbed_bits));
639  arr->~FixedArrType();
640 }
641 #endif // __GNUC__
642 
643 TEST(AllocatorSupportTest, CountInlineAllocations) {
644  constexpr size_t inlined_size = 4;
646  using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
647 
648  int64_t allocated = 0;
649  int64_t active_instances = 0;
650 
651  {
652  const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
653 
654  Alloc alloc(&allocated, &active_instances);
655 
656  AllocFxdArr arr(ia, ia + inlined_size, alloc);
657  static_cast<void>(arr);
658  }
659 
660  EXPECT_EQ(allocated, 0);
661  EXPECT_EQ(active_instances, 0);
662 }
663 
664 TEST(AllocatorSupportTest, CountOutoflineAllocations) {
665  constexpr size_t inlined_size = 4;
667  using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
668 
669  int64_t allocated = 0;
670  int64_t active_instances = 0;
671 
672  {
673  const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
674  Alloc alloc(&allocated, &active_instances);
675 
676  AllocFxdArr arr(ia, ia + ABSL_ARRAYSIZE(ia), alloc);
677 
678  EXPECT_EQ(allocated, arr.size() * sizeof(int));
679  static_cast<void>(arr);
680  }
681 
682  EXPECT_EQ(active_instances, 0);
683 }
684 
685 TEST(AllocatorSupportTest, CountCopyInlineAllocations) {
686  constexpr size_t inlined_size = 4;
688  using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
689 
690  int64_t allocated1 = 0;
691  int64_t allocated2 = 0;
692  int64_t active_instances = 0;
693  Alloc alloc(&allocated1, &active_instances);
694  Alloc alloc2(&allocated2, &active_instances);
695 
696  {
697  int initial_value = 1;
698 
699  AllocFxdArr arr1(inlined_size / 2, initial_value, alloc);
700 
701  EXPECT_EQ(allocated1, 0);
702 
703  AllocFxdArr arr2(arr1, alloc2);
704 
705  EXPECT_EQ(allocated2, 0);
706  static_cast<void>(arr1);
707  static_cast<void>(arr2);
708  }
709 
710  EXPECT_EQ(active_instances, 0);
711 }
712 
713 TEST(AllocatorSupportTest, CountCopyOutoflineAllocations) {
714  constexpr size_t inlined_size = 4;
716  using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
717 
718  int64_t allocated1 = 0;
719  int64_t allocated2 = 0;
720  int64_t active_instances = 0;
721  Alloc alloc(&allocated1, &active_instances);
722  Alloc alloc2(&allocated2, &active_instances);
723 
724  {
725  int initial_value = 1;
726 
727  AllocFxdArr arr1(inlined_size * 2, initial_value, alloc);
728 
729  EXPECT_EQ(allocated1, arr1.size() * sizeof(int));
730 
731  AllocFxdArr arr2(arr1, alloc2);
732 
733  EXPECT_EQ(allocated2, inlined_size * 2 * sizeof(int));
734  static_cast<void>(arr1);
735  static_cast<void>(arr2);
736  }
737 
738  EXPECT_EQ(active_instances, 0);
739 }
740 
741 TEST(AllocatorSupportTest, SizeValAllocConstructor) {
742  using testing::AllOf;
743  using testing::Each;
744  using testing::SizeIs;
745 
746  constexpr size_t inlined_size = 4;
748  using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
749 
750  {
751  auto len = inlined_size / 2;
752  auto val = 0;
753  int64_t allocated = 0;
754  AllocFxdArr arr(len, val, Alloc(&allocated));
755 
756  EXPECT_EQ(allocated, 0);
757  EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
758  }
759 
760  {
761  auto len = inlined_size * 2;
762  auto val = 0;
763  int64_t allocated = 0;
764  AllocFxdArr arr(len, val, Alloc(&allocated));
765 
766  EXPECT_EQ(allocated, len * sizeof(int));
767  EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
768  }
769 }
770 
771 #ifdef ABSL_HAVE_ADDRESS_SANITIZER
772 TEST(FixedArrayTest, AddressSanitizerAnnotations1) {
774  int* raw = a.data();
775  raw[0] = 0;
776  raw[9] = 0;
777  EXPECT_DEATH_IF_SUPPORTED(raw[-2] = 0, "container-overflow");
778  EXPECT_DEATH_IF_SUPPORTED(raw[-1] = 0, "container-overflow");
779  EXPECT_DEATH_IF_SUPPORTED(raw[10] = 0, "container-overflow");
780  EXPECT_DEATH_IF_SUPPORTED(raw[31] = 0, "container-overflow");
781 }
782 
783 TEST(FixedArrayTest, AddressSanitizerAnnotations2) {
785  char* raw = a.data();
786  raw[0] = 0;
787  raw[11] = 0;
788  EXPECT_DEATH_IF_SUPPORTED(raw[-7] = 0, "container-overflow");
789  EXPECT_DEATH_IF_SUPPORTED(raw[-1] = 0, "container-overflow");
790  EXPECT_DEATH_IF_SUPPORTED(raw[12] = 0, "container-overflow");
791  EXPECT_DEATH_IF_SUPPORTED(raw[17] = 0, "container-overflow");
792 }
793 
794 TEST(FixedArrayTest, AddressSanitizerAnnotations3) {
796  uint64_t* raw = a.data();
797  raw[0] = 0;
798  raw[19] = 0;
799  EXPECT_DEATH_IF_SUPPORTED(raw[-1] = 0, "container-overflow");
800  EXPECT_DEATH_IF_SUPPORTED(raw[20] = 0, "container-overflow");
801 }
802 
803 TEST(FixedArrayTest, AddressSanitizerAnnotations4) {
805  ThreeInts* raw = a.data();
806  raw[0] = ThreeInts();
807  raw[9] = ThreeInts();
808  // Note: raw[-1] is pointing to 12 bytes before the container range. However,
809  // there is only a 8-byte red zone before the container range, so we only
810  // access the last 4 bytes of the struct to make sure it stays within the red
811  // zone.
812  EXPECT_DEATH_IF_SUPPORTED(raw[-1].z_ = 0, "container-overflow");
813  EXPECT_DEATH_IF_SUPPORTED(raw[10] = ThreeInts(), "container-overflow");
814  // The actual size of storage is kDefaultBytes=256, 21*12 = 252,
815  // so reading raw[21] should still trigger the correct warning.
816  EXPECT_DEATH_IF_SUPPORTED(raw[21] = ThreeInts(), "container-overflow");
817 }
818 #endif // ABSL_HAVE_ADDRESS_SANITIZER
819 
820 TEST(FixedArrayTest, AbslHashValueWorks) {
821  using V = absl::FixedArray<int>;
822  std::vector<V> cases;
823 
824  // Generate a variety of vectors some of these are small enough for the inline
825  // space but are stored out of line.
826  for (int i = 0; i < 10; ++i) {
827  V v(i);
828  for (int j = 0; j < i; ++j) {
829  v[j] = j;
830  }
831  cases.push_back(v);
832  }
833 
835 }
836 
837 } // namespace
xds_interop_client.str
str
Definition: xds_interop_client.py:487
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
fixed
int fixed(struct state *s)
Definition: bloaty/third_party/zlib/contrib/puff/puff.c:536
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
get
absl::string_view get(const Cont &c)
Definition: abseil-cpp/absl/strings/str_replace_test.cc:185
memset
return memset(p, 0, total)
begin
char * begin
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1007
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
capacity
uint16_t capacity
Definition: protobuf/src/google/protobuf/descriptor.cc:948
kInput
static const uint8_t kInput[]
Definition: chacha_test.cc:44
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
array
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern array
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/array.c:111
absl::str_format_internal::AllOf
constexpr bool AllOf()
Definition: abseil-cpp/absl/strings/internal/str_format/checker.h:39
x_
X x_
Definition: abseil-cpp/absl/strings/internal/str_format/arg_test.cc:35
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::FixedArray::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: abseil-cpp/absl/container/fixed_array.h:114
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
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::FixedArray::back
reference back()
Definition: abseil-cpp/absl/container/fixed_array.h:266
env.new
def new
Definition: env.py:51
ABSL_ARRAYSIZE
#define ABSL_ARRAYSIZE(array)
Definition: abseil-cpp/absl/base/macros.h:44
T
#define T(upbtypeconst, upbtype, ctype, default_value)
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
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
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
absl::FixedArray::data
const_pointer data() const
Definition: abseil-cpp/absl/container/fixed_array.h:204
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
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
array
Definition: undname.c:101
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
TEST
#define TEST(name, init_size,...)
Definition: arena_test.cc:75
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
counter
static int counter
Definition: abseil-cpp/absl/flags/reflection_test.cc:131
testing::SizeIs
internal::SizeIsMatcher< SizeMatcher > SizeIs(const SizeMatcher &size_matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8947
absl::flags_internal::Alloc
void * Alloc(FlagOpFn op)
Definition: abseil-cpp/absl/flags/internal/flag.h:102
a1
T::first_type a1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:305
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
xds_manager.items
items
Definition: xds_manager.py:55
EXPECT_DEATH_IF_SUPPORTED
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-death-test.h:335
absl::FixedArray::front
reference front()
Definition: abseil-cpp/absl/container/fixed_array.h:251
Empty
Definition: abseil-cpp/absl/container/internal/compressed_tuple_test.cc:33
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
value_
int value_
Definition: orphanable_test.cc:38
value
const char * value
Definition: hpack_parser_table.cc:165
ASSERT_NO_FATAL_FAILURE
#define ASSERT_NO_FATAL_FAILURE(statement)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2199
absl::container_internal::CountingAllocator
Definition: abseil-cpp/absl/container/internal/counting_allocator.h:33
absl::FixedArray::size
size_type size() const
Definition: abseil-cpp/absl/container/fixed_array.h:179
absl::FixedArray::begin
iterator begin()
Definition: abseil-cpp/absl/container/fixed_array.h:281
absl::FixedArray::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: abseil-cpp/absl/container/fixed_array.h:115
NotTriviallyCopyable
Definition: donotoptimize_assembly_test.cc:15
cpp.gmock_class.set
set
Definition: bloaty/third_party/googletest/googlemock/scripts/generator/cpp/gmock_class.py:44
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
testing::AllOf
internal::AllOfResult2< M1, M2 >::type AllOf(M1 m1, M2 m2)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:13472
iter
Definition: test_winkernel.cpp:47
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
testing::Each
internal::EachMatcher< M > Each(M matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:9133
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
absl::FixedArray
Definition: abseil-cpp/absl/container/fixed_array.h:78
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
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:23