1 // Copyright 2016 The Android Open Source Project
3 // This software is licensed under the terms of the GNU General Public
4 // License version 2, as published by the Free Software Foundation, and
5 // may be copied, distributed, and modified under those terms.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License for more details.
12 #include "anbox/common/small_vector.h"
13 #include "anbox/common/scope_ptr.h"
14 #include "anbox/testing/gtest_utils.h"
16 #include <gtest/gtest.h>
22 TEST(SmallVector, basic) {
23 SmallFixedVector<char, 10> sv;
24 EXPECT_EQ(sv.size(), 0);
25 EXPECT_TRUE(sv.empty());
27 EXPECT_EQ(10, sv.capacity());
28 EXPECT_FALSE(sv.isAllocated());
30 const int values[] = {1, 2, 3};
31 sv = SmallFixedVector<char, 10>(values, values + 3);
32 EXPECT_EQ(3, sv.size());
33 EXPECT_FALSE(sv.empty());
34 EXPECT_EQ(10, sv.capacity());
35 EXPECT_FALSE(sv.isAllocated());
36 EXPECT_TRUE(anbox::testing::RangesMatch(values, sv));
39 EXPECT_EQ(0, sv.size());
40 EXPECT_TRUE(sv.empty());
42 const char str[] = "this is a long string for insertion";
43 sv = SmallFixedVector<char, 10>(str);
44 EXPECT_EQ(sizeof(str), sv.size());
45 EXPECT_GT(sv.capacity(), 10);
46 EXPECT_TRUE(sv.isAllocated());
47 EXPECT_TRUE(anbox::testing::RangesMatch(str, sv));
49 // make sure explicit loops over indices and iterators work
50 for (size_t i = 0; i != sv.size(); ++i) {
51 EXPECT_EQ(str[i], sv[i]);
58 for (auto it = sv.begin(); it != sv.end(); ++it, ++c) {
63 for (auto it = sv.data(); it != sv.data() + sv.size(); ++it, ++c) {
68 TEST(SmallVector, ctor) {
70 SmallFixedVector<int, 1> sv;
71 EXPECT_EQ(sv.size(), 0);
75 const int values[] = {1, 2, 3};
76 SmallFixedVector<int, 10> sv(values, values + 3);
77 EXPECT_TRUE(anbox::testing::RangesMatch(values, sv));
81 const int values[] = {1, 2, 3};
82 SmallFixedVector<int, 10> sv(values);
83 EXPECT_TRUE(anbox::testing::RangesMatch(values, sv));
87 const int values[] = {1, 2, 3};
88 SmallFixedVector<int, 10> sv(values);
89 EXPECT_TRUE(anbox::testing::RangesMatch(values, sv));
93 const int values[] = {1, 2, 3};
94 SmallFixedVector<int, 10> sv = {1, 2, 3};
95 EXPECT_TRUE(anbox::testing::RangesMatch(values, sv));
99 const int values[] = {1, 2, 3};
100 SmallFixedVector<int, 10> sv1(values);
101 SmallFixedVector<int, 10> sv2(sv1);
103 EXPECT_TRUE(anbox::testing::RangesMatch(values, sv1));
104 EXPECT_TRUE(anbox::testing::RangesMatch(sv2, sv1));
106 SmallFixedVector<int, 10> sv3(std::move(sv1));
107 EXPECT_TRUE(anbox::testing::RangesMatch(sv3, values));
108 // don't check |sv1| - it is not required to be empty.
112 TEST(SmallVector, dtor) {
113 // Count all destructor calls for the elements and make sure they're called
115 int destructedTimes = 0;
116 auto deleter = [](int* p) { ++(*p); };
117 auto item1 = makeCustomScopedPtr(&destructedTimes, deleter);
118 auto item2 = makeCustomScopedPtr(&destructedTimes, deleter);
119 auto item3 = makeCustomScopedPtr(&destructedTimes, deleter);
122 SmallFixedVector<decltype(item1), 1> sv;
123 sv.emplace_back(std::move(item1));
124 sv.emplace_back(std::move(item2));
125 // this one is already empty, so it won't add to |destructedTimes|.
126 sv.emplace_back(std::move(item2));
127 sv.emplace_back(std::move(item3));
130 EXPECT_EQ(3, destructedTimes);
133 TEST(SmallVector, modifiers) {
134 SmallFixedVector<unsigned, 5> sv;
136 EXPECT_EQ(0, sv.size());
137 EXPECT_EQ(5, sv.capacity());
140 EXPECT_EQ(0, sv.size());
141 EXPECT_EQ(5, sv.capacity());
142 EXPECT_FALSE(sv.isAllocated());
145 EXPECT_EQ(0, sv.size());
146 EXPECT_EQ(6, sv.capacity());
147 EXPECT_TRUE(sv.isAllocated());
150 EXPECT_EQ(3, sv.size());
151 EXPECT_EQ(6, sv.capacity());
152 EXPECT_TRUE(sv.isAllocated());
155 EXPECT_EQ(10, sv.size());
156 EXPECT_GE(sv.capacity(), 10);
157 EXPECT_TRUE(sv.isAllocated());
160 EXPECT_EQ(11, sv.size());
161 EXPECT_GE(sv.capacity(), 11);
164 EXPECT_EQ(12, sv.size());
165 EXPECT_GE(sv.capacity(), 12);
168 EXPECT_EQ(0, sv.size());
169 EXPECT_GE(sv.capacity(), 12);
171 // resize_noinit() doesn't really have anything specific we can test
172 // compared to resize()
174 EXPECT_EQ(1, sv.size());
175 EXPECT_GE(sv.capacity(), 12);
177 sv.resize_noinit(100);
178 EXPECT_EQ(100, sv.size());
179 EXPECT_GE(sv.capacity(), 100);
181 SmallFixedVector<std::string, 5> strings = {"a", "b", "c"};
182 strings.emplace_back("d");
183 strings.push_back("e");
184 EXPECT_EQ(5, strings.size());
185 EXPECT_EQ(5, strings.capacity());
186 EXPECT_FALSE(strings.isAllocated());
188 strings.push_back(std::string("e"));
189 EXPECT_EQ(6, strings.size());
190 EXPECT_GE(strings.capacity(), 6);
191 EXPECT_TRUE(strings.isAllocated());
194 TEST(SmallVector, useThroughInterface) {
195 SmallFixedVector<int, 10> sfv = {1, 2, 3};
196 SmallVector<int>& sv = sfv;
197 EXPECT_TRUE(anbox::testing::RangesMatch(sv, sfv));
198 EXPECT_EQ(sv.isAllocated(), sfv.isAllocated());
201 EXPECT_TRUE(sv.isAllocated());
202 EXPECT_EQ(sv.isAllocated(), sfv.isAllocated());
204 // now make sure that deleting through base class cleans up the memory
206 int destructedTimes = 0;
207 auto deleter = [](int* p) { ++(*p); };
208 auto item1 = makeCustomScopedPtr(&destructedTimes, deleter);
209 auto item2 = makeCustomScopedPtr(&destructedTimes, deleter);
210 SmallVector<decltype(item1)>* sv =
211 new SmallFixedVector<decltype(item1), 1>();
212 sv->push_back(std::move(item1));
213 sv->emplace_back(std::move(item2));
215 EXPECT_EQ(2, destructedTimes);
218 } // namespace common