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 
TEST_F(ContainersVectorTest,Empty)26 TEST_F(ContainersVectorTest, Empty) {
27   marl::containers::vector<std::string, 4> vector(allocator);
28   ASSERT_EQ(vector.size(), size_t(0));
29 }
30 
TEST_F(ContainersVectorTest,WithinFixedCapIndex)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 
TEST_F(ContainersVectorTest,BeyondFixedCapIndex)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 
TEST_F(ContainersVectorTest,WithinFixedCapPushPop)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 
TEST_F(ContainersVectorTest,BeyondFixedCapPushPop)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 
TEST_F(ContainersVectorTest,CopyConstruct)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 
TEST_F(ContainersVectorTest,CopyConstructDifferentBaseCapacity)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 
TEST_F(ContainersVectorTest,CopyAssignment)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 
TEST_F(ContainersVectorTest,CopyAssignmentDifferentBaseCapacity)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 
TEST_F(ContainersVectorTest,MoveConstruct)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 
TEST_F(ContainersVectorTest,Copy)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 
TEST_F(ContainersVectorTest,Move)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 
TEST_F(ContainersListTest,Empty)246 TEST_F(ContainersListTest, Empty) {
247   marl::containers::list<std::string> list(allocator);
248   ASSERT_EQ(list.size(), size_t(0));
249 }
250 
TEST_F(ContainersListTest,EmplaceOne)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 
TEST_F(ContainersListTest,EmplaceThree)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 
TEST_F(ContainersListTest,EraseFront)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 
TEST_F(ContainersListTest,EraseBack)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 
TEST_F(ContainersListTest,EraseMid)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 
TEST_F(ContainersListTest,Grow)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