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