xref: /aosp_15_r20/external/deqp/framework/delibs/decpp/dePoolArray.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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