1 | // Copyright 2019 The Marl 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 "marl/containers.h" |
16 | #include "marl_test.h" |
17 | |
18 | #include "gmock/gmock.h" |
19 | #include "gtest/gtest.h" |
20 | |
21 | #include <cstddef> |
22 | #include <string> |
23 | |
24 | class ContainersVectorTest : public WithoutBoundScheduler {}; |
25 | |
26 | TEST_F(ContainersVectorTest, Empty) { |
27 | marl::containers::vector<std::string, 4> vector(allocator); |
28 | ASSERT_EQ(vector.size(), size_t(0)); |
29 | } |
30 | |
31 | TEST_F(ContainersVectorTest, WithinFixedCapIndex) { |
32 | marl::containers::vector<std::string, 4> vector(allocator); |
33 | vector.resize(4); |
34 | vector[0] = "A" ; |
35 | vector[1] = "B" ; |
36 | vector[2] = "C" ; |
37 | vector[3] = "D" ; |
38 | |
39 | ASSERT_EQ(vector[0], "A" ); |
40 | ASSERT_EQ(vector[1], "B" ); |
41 | ASSERT_EQ(vector[2], "C" ); |
42 | ASSERT_EQ(vector[3], "D" ); |
43 | } |
44 | |
45 | TEST_F(ContainersVectorTest, BeyondFixedCapIndex) { |
46 | marl::containers::vector<std::string, 1> vector(allocator); |
47 | vector.resize(4); |
48 | vector[0] = "A" ; |
49 | vector[1] = "B" ; |
50 | vector[2] = "C" ; |
51 | vector[3] = "D" ; |
52 | |
53 | ASSERT_EQ(vector[0], "A" ); |
54 | ASSERT_EQ(vector[1], "B" ); |
55 | ASSERT_EQ(vector[2], "C" ); |
56 | ASSERT_EQ(vector[3], "D" ); |
57 | } |
58 | |
59 | TEST_F(ContainersVectorTest, WithinFixedCapPushPop) { |
60 | marl::containers::vector<std::string, 4> vector(allocator); |
61 | vector.push_back("A" ); |
62 | vector.push_back("B" ); |
63 | vector.push_back("C" ); |
64 | vector.push_back("D" ); |
65 | |
66 | ASSERT_EQ(vector.size(), size_t(4)); |
67 | ASSERT_EQ(vector.end() - vector.begin(), ptrdiff_t(4)); |
68 | |
69 | ASSERT_EQ(vector.front(), "A" ); |
70 | ASSERT_EQ(vector.back(), "D" ); |
71 | vector.pop_back(); |
72 | ASSERT_EQ(vector.size(), size_t(3)); |
73 | ASSERT_EQ(vector.end() - vector.begin(), ptrdiff_t(3)); |
74 | |
75 | ASSERT_EQ(vector.front(), "A" ); |
76 | ASSERT_EQ(vector.back(), "C" ); |
77 | vector.pop_back(); |
78 | ASSERT_EQ(vector.size(), size_t(2)); |
79 | ASSERT_EQ(vector.end() - vector.begin(), ptrdiff_t(2)); |
80 | |
81 | ASSERT_EQ(vector.front(), "A" ); |
82 | ASSERT_EQ(vector.back(), "B" ); |
83 | vector.pop_back(); |
84 | ASSERT_EQ(vector.size(), size_t(1)); |
85 | ASSERT_EQ(vector.end() - vector.begin(), ptrdiff_t(1)); |
86 | |
87 | ASSERT_EQ(vector.front(), "A" ); |
88 | ASSERT_EQ(vector.back(), "A" ); |
89 | vector.pop_back(); |
90 | ASSERT_EQ(vector.size(), size_t(0)); |
91 | } |
92 | |
93 | TEST_F(ContainersVectorTest, BeyondFixedCapPushPop) { |
94 | marl::containers::vector<std::string, 2> vector(allocator); |
95 | vector.push_back("A" ); |
96 | vector.push_back("B" ); |
97 | vector.push_back("C" ); |
98 | vector.push_back("D" ); |
99 | |
100 | ASSERT_EQ(vector.size(), size_t(4)); |
101 | ASSERT_EQ(vector.end() - vector.begin(), ptrdiff_t(4)); |
102 | |
103 | ASSERT_EQ(vector.front(), "A" ); |
104 | ASSERT_EQ(vector.back(), "D" ); |
105 | vector.pop_back(); |
106 | ASSERT_EQ(vector.size(), size_t(3)); |
107 | ASSERT_EQ(vector.end() - vector.begin(), ptrdiff_t(3)); |
108 | |
109 | ASSERT_EQ(vector.front(), "A" ); |
110 | ASSERT_EQ(vector.back(), "C" ); |
111 | vector.pop_back(); |
112 | ASSERT_EQ(vector.size(), size_t(2)); |
113 | ASSERT_EQ(vector.end() - vector.begin(), ptrdiff_t(2)); |
114 | |
115 | ASSERT_EQ(vector.front(), "A" ); |
116 | ASSERT_EQ(vector.back(), "B" ); |
117 | vector.pop_back(); |
118 | ASSERT_EQ(vector.size(), size_t(1)); |
119 | ASSERT_EQ(vector.end() - vector.begin(), ptrdiff_t(1)); |
120 | |
121 | ASSERT_EQ(vector.front(), "A" ); |
122 | ASSERT_EQ(vector.back(), "A" ); |
123 | vector.pop_back(); |
124 | ASSERT_EQ(vector.size(), size_t(0)); |
125 | } |
126 | |
127 | TEST_F(ContainersVectorTest, CopyConstruct) { |
128 | marl::containers::vector<std::string, 4> vectorA(allocator); |
129 | |
130 | vectorA.resize(3); |
131 | vectorA[0] = "A" ; |
132 | vectorA[1] = "B" ; |
133 | vectorA[2] = "C" ; |
134 | |
135 | marl::containers::vector<std::string, 4> vectorB(vectorA, allocator); |
136 | ASSERT_EQ(vectorB.size(), size_t(3)); |
137 | ASSERT_EQ(vectorB[0], "A" ); |
138 | ASSERT_EQ(vectorB[1], "B" ); |
139 | ASSERT_EQ(vectorB[2], "C" ); |
140 | } |
141 | |
142 | TEST_F(ContainersVectorTest, CopyConstructDifferentBaseCapacity) { |
143 | marl::containers::vector<std::string, 4> vectorA(allocator); |
144 | |
145 | vectorA.resize(3); |
146 | vectorA[0] = "A" ; |
147 | vectorA[1] = "B" ; |
148 | vectorA[2] = "C" ; |
149 | |
150 | marl::containers::vector<std::string, 2> vectorB(vectorA, allocator); |
151 | ASSERT_EQ(vectorB.size(), size_t(3)); |
152 | ASSERT_EQ(vectorB[0], "A" ); |
153 | ASSERT_EQ(vectorB[1], "B" ); |
154 | ASSERT_EQ(vectorB[2], "C" ); |
155 | } |
156 | |
157 | TEST_F(ContainersVectorTest, CopyAssignment) { |
158 | marl::containers::vector<std::string, 4> vectorA(allocator); |
159 | |
160 | vectorA.resize(3); |
161 | vectorA[0] = "A" ; |
162 | vectorA[1] = "B" ; |
163 | vectorA[2] = "C" ; |
164 | |
165 | marl::containers::vector<std::string, 4> vectorB(allocator); |
166 | vectorB = vectorA; |
167 | ASSERT_EQ(vectorB.size(), size_t(3)); |
168 | ASSERT_EQ(vectorB[0], "A" ); |
169 | ASSERT_EQ(vectorB[1], "B" ); |
170 | ASSERT_EQ(vectorB[2], "C" ); |
171 | } |
172 | |
173 | TEST_F(ContainersVectorTest, CopyAssignmentDifferentBaseCapacity) { |
174 | marl::containers::vector<std::string, 4> vectorA(allocator); |
175 | |
176 | vectorA.resize(3); |
177 | vectorA[0] = "A" ; |
178 | vectorA[1] = "B" ; |
179 | vectorA[2] = "C" ; |
180 | |
181 | marl::containers::vector<std::string, 2> vectorB(allocator); |
182 | vectorB = vectorA; |
183 | ASSERT_EQ(vectorB.size(), size_t(3)); |
184 | ASSERT_EQ(vectorB[0], "A" ); |
185 | ASSERT_EQ(vectorB[1], "B" ); |
186 | ASSERT_EQ(vectorB[2], "C" ); |
187 | } |
188 | |
189 | TEST_F(ContainersVectorTest, MoveConstruct) { |
190 | marl::containers::vector<std::string, 4> vectorA(allocator); |
191 | |
192 | vectorA.resize(3); |
193 | vectorA[0] = "A" ; |
194 | vectorA[1] = "B" ; |
195 | vectorA[2] = "C" ; |
196 | |
197 | marl::containers::vector<std::string, 2> vectorB(std::move(vectorA), |
198 | allocator); |
199 | ASSERT_EQ(vectorB.size(), size_t(3)); |
200 | ASSERT_EQ(vectorB[0], "A" ); |
201 | ASSERT_EQ(vectorB[1], "B" ); |
202 | ASSERT_EQ(vectorB[2], "C" ); |
203 | } |
204 | |
205 | TEST_F(ContainersVectorTest, Copy) { |
206 | marl::containers::vector<std::string, 4> vectorA(allocator); |
207 | marl::containers::vector<std::string, 2> vectorB(allocator); |
208 | |
209 | vectorA.resize(3); |
210 | vectorA[0] = "A" ; |
211 | vectorA[1] = "B" ; |
212 | vectorA[2] = "C" ; |
213 | |
214 | vectorB.resize(1); |
215 | vectorB[0] = "Z" ; |
216 | |
217 | vectorB = vectorA; |
218 | ASSERT_EQ(vectorB.size(), size_t(3)); |
219 | ASSERT_EQ(vectorB[0], "A" ); |
220 | ASSERT_EQ(vectorB[1], "B" ); |
221 | ASSERT_EQ(vectorB[2], "C" ); |
222 | } |
223 | |
224 | TEST_F(ContainersVectorTest, Move) { |
225 | marl::containers::vector<std::string, 4> vectorA(allocator); |
226 | marl::containers::vector<std::string, 2> vectorB(allocator); |
227 | |
228 | vectorA.resize(3); |
229 | vectorA[0] = "A" ; |
230 | vectorA[1] = "B" ; |
231 | vectorA[2] = "C" ; |
232 | |
233 | vectorB.resize(1); |
234 | vectorB[0] = "Z" ; |
235 | |
236 | vectorB = std::move(vectorA); |
237 | ASSERT_EQ(vectorA.size(), size_t(0)); |
238 | ASSERT_EQ(vectorB.size(), size_t(3)); |
239 | ASSERT_EQ(vectorB[0], "A" ); |
240 | ASSERT_EQ(vectorB[1], "B" ); |
241 | ASSERT_EQ(vectorB[2], "C" ); |
242 | } |
243 | |
244 | class ContainersListTest : public WithoutBoundScheduler {}; |
245 | |
246 | TEST_F(ContainersListTest, Empty) { |
247 | marl::containers::list<std::string> list(allocator); |
248 | ASSERT_EQ(list.size(), size_t(0)); |
249 | } |
250 | |
251 | TEST_F(ContainersListTest, EmplaceOne) { |
252 | marl::containers::list<std::string> list(allocator); |
253 | auto itEntry = list.emplace_front("hello world" ); |
254 | ASSERT_EQ(*itEntry, "hello world" ); |
255 | ASSERT_EQ(list.size(), size_t(1)); |
256 | auto it = list.begin(); |
257 | ASSERT_EQ(it, itEntry); |
258 | ++it; |
259 | ASSERT_EQ(it, list.end()); |
260 | } |
261 | |
262 | TEST_F(ContainersListTest, EmplaceThree) { |
263 | marl::containers::list<std::string> list(allocator); |
264 | auto itA = list.emplace_front("a" ); |
265 | auto itB = list.emplace_front("b" ); |
266 | auto itC = list.emplace_front("c" ); |
267 | ASSERT_EQ(*itA, "a" ); |
268 | ASSERT_EQ(*itB, "b" ); |
269 | ASSERT_EQ(*itC, "c" ); |
270 | ASSERT_EQ(list.size(), size_t(3)); |
271 | auto it = list.begin(); |
272 | ASSERT_EQ(it, itC); |
273 | ++it; |
274 | ASSERT_EQ(it, itB); |
275 | ++it; |
276 | ASSERT_EQ(it, itA); |
277 | ++it; |
278 | ASSERT_EQ(it, list.end()); |
279 | } |
280 | |
281 | TEST_F(ContainersListTest, EraseFront) { |
282 | marl::containers::list<std::string> list(allocator); |
283 | auto itA = list.emplace_front("a" ); |
284 | auto itB = list.emplace_front("b" ); |
285 | auto itC = list.emplace_front("c" ); |
286 | list.erase(itC); |
287 | ASSERT_EQ(list.size(), size_t(2)); |
288 | auto it = list.begin(); |
289 | ASSERT_EQ(it, itB); |
290 | ++it; |
291 | ASSERT_EQ(it, itA); |
292 | ++it; |
293 | ASSERT_EQ(it, list.end()); |
294 | } |
295 | |
296 | TEST_F(ContainersListTest, EraseBack) { |
297 | marl::containers::list<std::string> list(allocator); |
298 | auto itA = list.emplace_front("a" ); |
299 | auto itB = list.emplace_front("b" ); |
300 | auto itC = list.emplace_front("c" ); |
301 | list.erase(itA); |
302 | ASSERT_EQ(list.size(), size_t(2)); |
303 | auto it = list.begin(); |
304 | ASSERT_EQ(it, itC); |
305 | ++it; |
306 | ASSERT_EQ(it, itB); |
307 | ++it; |
308 | ASSERT_EQ(it, list.end()); |
309 | } |
310 | |
311 | TEST_F(ContainersListTest, EraseMid) { |
312 | marl::containers::list<std::string> list(allocator); |
313 | auto itA = list.emplace_front("a" ); |
314 | auto itB = list.emplace_front("b" ); |
315 | auto itC = list.emplace_front("c" ); |
316 | list.erase(itB); |
317 | ASSERT_EQ(list.size(), size_t(2)); |
318 | auto it = list.begin(); |
319 | ASSERT_EQ(it, itC); |
320 | ++it; |
321 | ASSERT_EQ(it, itA); |
322 | ++it; |
323 | ASSERT_EQ(it, list.end()); |
324 | } |
325 | |
326 | TEST_F(ContainersListTest, Grow) { |
327 | marl::containers::list<std::string> list(allocator); |
328 | for (int i = 0; i < 256; i++) { |
329 | list.emplace_front(std::to_string(i)); |
330 | } |
331 | ASSERT_EQ(list.size(), size_t(256)); |
332 | } |
333 | |