1 /*-------------------------------------------------------------------------
2 * drawElements C++ Base Library
3 * -----------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Array template backed by memory pool.
22 *//*--------------------------------------------------------------------*/
23
24 #include "dePoolArray.hpp"
25
26 #include <algorithm>
27 #include <vector>
28
29 namespace de
30 {
31
intArrayTest(void)32 static void intArrayTest(void)
33 {
34 MemPool pool;
35 PoolArray<int> arr(&pool);
36 PoolArray<uint16_t> arr16(&pool);
37 int i;
38
39 /* Test pushBack(). */
40 for (i = 0; i < 5000; i++)
41 {
42 /* Unused alloc to try to break alignments. */
43 pool.alloc(1);
44
45 arr.pushBack(i);
46 arr16.pushBack((int16_t)i);
47 }
48
49 DE_TEST_ASSERT(arr.size() == 5000);
50 DE_TEST_ASSERT(arr16.size() == 5000);
51 for (i = 0; i < 5000; i++)
52 {
53 DE_TEST_ASSERT(arr[i] == i);
54 DE_TEST_ASSERT(arr16[i] == i);
55 }
56
57 /* Test popBack(). */
58 for (i = 0; i < 1000; i++)
59 {
60 DE_TEST_ASSERT(arr.popBack() == (4999 - i));
61 DE_TEST_ASSERT(arr16.popBack() == (4999 - i));
62 }
63
64 DE_TEST_ASSERT(arr.size() == 4000);
65 DE_TEST_ASSERT(arr16.size() == 4000);
66 for (i = 0; i < 4000; i++)
67 {
68 DE_TEST_ASSERT(arr[i] == i);
69 DE_TEST_ASSERT(arr16[i] == i);
70 }
71
72 /* Test resize(). */
73 arr.resize(1000);
74 arr16.resize(1000);
75 for (i = 1000; i < 5000; i++)
76 {
77 arr.pushBack(i);
78 arr16.pushBack((int16_t)i);
79 }
80
81 DE_TEST_ASSERT(arr.size() == 5000);
82 DE_TEST_ASSERT(arr16.size() == 5000);
83 for (i = 0; i < 5000; i++)
84 {
85 DE_TEST_ASSERT(arr[i] == i);
86 DE_TEST_ASSERT(arr16[i] == i);
87 }
88
89 /* Test set() and pushBack() with reserve(). */
90 PoolArray<int> arr2(&pool);
91 arr2.resize(1500);
92 arr2.reserve(2000);
93 for (i = 0; i < 1500; i++)
94 arr2[i] = i;
95 for (; i < 5000; i++)
96 arr2.pushBack(i);
97
98 DE_TEST_ASSERT(arr2.size() == 5000);
99 for (i = 0; i < 5000; i++)
100 {
101 int val = arr2[i];
102 DE_TEST_ASSERT(val == i);
103 }
104 }
105
alignedIntArrayTest(void)106 static void alignedIntArrayTest(void)
107 {
108 MemPool pool;
109 PoolArray<int, 16> arr(&pool);
110 PoolArray<uint16_t, 8> arr16(&pool);
111 int i;
112
113 /* Test pushBack(). */
114 for (i = 0; i < 5000; i++)
115 {
116 /* Unused alloc to try to break alignments. */
117 pool.alloc(1);
118
119 arr.pushBack(i);
120 arr16.pushBack((int16_t)i);
121 }
122
123 DE_TEST_ASSERT(arr.size() == 5000);
124 DE_TEST_ASSERT(arr16.size() == 5000);
125 for (i = 0; i < 5000; i++)
126 {
127 DE_TEST_ASSERT(arr[i] == i);
128 DE_TEST_ASSERT(arr16[i] == i);
129 }
130
131 /* Test popBack(). */
132 for (i = 0; i < 1000; i++)
133 {
134 DE_TEST_ASSERT(arr.popBack() == (4999 - i));
135 DE_TEST_ASSERT(arr16.popBack() == (4999 - i));
136 }
137
138 DE_TEST_ASSERT(arr.size() == 4000);
139 DE_TEST_ASSERT(arr16.size() == 4000);
140 for (i = 0; i < 4000; i++)
141 {
142 DE_TEST_ASSERT(arr[i] == i);
143 DE_TEST_ASSERT(arr16[i] == i);
144 }
145
146 /* Test resize(). */
147 arr.resize(1000);
148 arr16.resize(1000);
149 for (i = 1000; i < 5000; i++)
150 {
151 arr.pushBack(i);
152 arr16.pushBack((int16_t)i);
153 }
154
155 DE_TEST_ASSERT(arr.size() == 5000);
156 DE_TEST_ASSERT(arr16.size() == 5000);
157 for (i = 0; i < 5000; i++)
158 {
159 DE_TEST_ASSERT(arr[i] == i);
160 DE_TEST_ASSERT(arr16[i] == i);
161 }
162
163 arr.resize(0);
164 arr.resize(100, -123);
165 DE_TEST_ASSERT(arr.size() == 100);
166 for (i = 0; i < 100; i++)
167 DE_TEST_ASSERT(arr[i] == -123);
168
169 /* Test set() and pushBack() with reserve(). */
170 PoolArray<int, 32> arr2(&pool);
171 arr2.resize(1500);
172 arr2.reserve(2000);
173 for (i = 0; i < 1500; i++)
174 arr2[i] = i;
175 for (; i < 5000; i++)
176 arr2.pushBack(i);
177
178 DE_TEST_ASSERT(arr2.size() == 5000);
179 for (i = 0; i < 5000; i++)
180 {
181 int val = arr2[i];
182 DE_TEST_ASSERT(val == i);
183 }
184 }
185
186 namespace
187 {
188
189 class RefCount
190 {
191 public:
RefCount(void)192 RefCount(void) : m_count(DE_NULL)
193 {
194 }
195
RefCount(int * count)196 RefCount(int *count) : m_count(count)
197 {
198 *m_count += 1;
199 }
200
RefCount(const RefCount & other)201 RefCount(const RefCount &other) : m_count(other.m_count)
202 {
203 if (m_count)
204 *m_count += 1;
205 }
206
~RefCount(void)207 ~RefCount(void)
208 {
209 if (m_count)
210 *m_count -= 1;
211 }
212
operator =(const RefCount & other)213 RefCount &operator=(const RefCount &other)
214 {
215 if (this == &other)
216 return *this;
217
218 if (m_count)
219 *m_count -= 1;
220
221 m_count = other.m_count;
222
223 if (m_count)
224 *m_count += 1;
225
226 return *this;
227 }
228
229 private:
230 int *m_count;
231 };
232
233 } // namespace
234
sideEffectTest(void)235 static void sideEffectTest(void)
236 {
237 MemPool pool;
238 PoolArray<RefCount> arr(&pool);
239 int count = 0;
240 RefCount counter(&count);
241
242 DE_TEST_ASSERT(count == 1);
243
244 for (int i = 0; i < 127; i++)
245 arr.pushBack(counter);
246
247 DE_TEST_ASSERT(count == 128);
248
249 for (int i = 0; i < 10; i++)
250 arr.popBack();
251
252 DE_TEST_ASSERT(count == 118);
253
254 arr.resize(150);
255 DE_TEST_ASSERT(count == 118);
256
257 arr.resize(18);
258 DE_TEST_ASSERT(count == 19);
259
260 arr.resize(19);
261 DE_TEST_ASSERT(count == 19);
262
263 arr.clear();
264 DE_TEST_ASSERT(count == 1);
265 }
266
iteratorTest(void)267 static void iteratorTest(void)
268 {
269 MemPool pool;
270 PoolArray<int> arr(&pool);
271
272 for (int ndx = 0; ndx < 128; ndx++)
273 arr.pushBack(ndx);
274
275 // ConstIterator
276 {
277 const PoolArray<int> &cRef = arr;
278 int ndx = 0;
279 for (PoolArray<int>::ConstIterator iter = cRef.begin(); iter != cRef.end(); iter++, ndx++)
280 {
281 DE_TEST_ASSERT(*iter == ndx);
282 }
283
284 // Cast & interop with non-const array.
285 ndx = 0;
286 for (PoolArray<int>::ConstIterator iter = arr.begin(); iter != arr.end(); iter++, ndx++)
287 {
288 DE_TEST_ASSERT(*iter == ndx);
289 }
290 }
291
292 // Arithmetics.
293 DE_TEST_ASSERT(arr.end() - arr.begin() == 128);
294 DE_TEST_ASSERT(*(arr.begin() + 3) == 3);
295 DE_TEST_ASSERT(arr.begin()[4] == 4);
296
297 // Relational
298 DE_TEST_ASSERT(arr.begin() != arr.begin() + 1);
299 DE_TEST_ASSERT(arr.begin() == arr.begin());
300 DE_TEST_ASSERT(arr.begin() != arr.end());
301 DE_TEST_ASSERT(arr.begin() < arr.end());
302 DE_TEST_ASSERT(arr.begin() < arr.begin() + 1);
303 DE_TEST_ASSERT(arr.begin() <= arr.begin());
304 DE_TEST_ASSERT(arr.end() > arr.begin());
305 DE_TEST_ASSERT(arr.begin() >= arr.begin());
306
307 // Compatibility with stl.
308 DE_TEST_ASSERT(std::distance(arr.begin(), arr.end()) == 128);
309
310 std::vector<int> vecCopy(arr.size());
311 std::copy(arr.begin(), arr.end(), vecCopy.begin());
312 for (int ndx = 0; ndx < (int)vecCopy.size(); ndx++)
313 DE_TEST_ASSERT(vecCopy[ndx] == ndx);
314
315 std::fill(arr.begin(), arr.end(), -1);
316 for (int ndx = 0; ndx < (int)arr.size(); ndx++)
317 DE_TEST_ASSERT(arr[ndx] == -1);
318
319 std::copy(vecCopy.begin(), vecCopy.end(), arr.begin());
320 for (int ndx = 0; ndx < (int)arr.size(); ndx++)
321 DE_TEST_ASSERT(arr[ndx] == ndx);
322
323 // Iterator
324 {
325 int ndx = 0;
326 for (PoolArray<int>::Iterator iter = arr.begin(); iter != arr.end(); iter++, ndx++)
327 {
328 DE_TEST_ASSERT(*iter == ndx);
329 if (ndx == 4)
330 *iter = 0;
331 else if (ndx == 7)
332 *(iter - 1) = 1;
333 }
334 }
335
336 DE_TEST_ASSERT(arr[4] == 0);
337 DE_TEST_ASSERT(arr[6] == 1);
338 }
339
PoolArray_selfTest(void)340 void PoolArray_selfTest(void)
341 {
342 intArrayTest();
343 alignedIntArrayTest();
344 sideEffectTest();
345 iteratorTest();
346 }
347
348 } // namespace de
349