Home | History | Annotate | Download | only in decpp
      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 
     32 static void intArrayTest (void)
     33 {
     34 	MemPool				pool;
     35 	PoolArray<int>		arr		(&pool);
     36 	PoolArray<deUint16>	arr16	(&pool);
     37 	int					i;
     38 
     39 	/* Test pushBack(). */
     40 	for (i = 0; i < 5000; i++)
     41 	{
     42 		/* Dummy alloc to try to break alignments. */
     43 		pool.alloc(1);
     44 
     45 		arr.pushBack(i);
     46 		arr16.pushBack((deInt16)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((deInt16)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 
    106 static void alignedIntArrayTest (void)
    107 {
    108 	MemPool					pool;
    109 	PoolArray<int, 16>		arr		(&pool);
    110 	PoolArray<deUint16,	8>	arr16	(&pool);
    111 	int						i;
    112 
    113 	/* Test pushBack(). */
    114 	for (i = 0; i < 5000; i++)
    115 	{
    116 		/* Dummy alloc to try to break alignments. */
    117 		pool.alloc(1);
    118 
    119 		arr.pushBack(i);
    120 		arr16.pushBack((deInt16)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((deInt16)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:
    192 	RefCount (void)
    193 		: m_count(DE_NULL)
    194 	{
    195 	}
    196 
    197 	RefCount (int* count)
    198 		: m_count(count)
    199 	{
    200 		*m_count += 1;
    201 	}
    202 
    203 	RefCount (const RefCount& other)
    204 		: m_count(other.m_count)
    205 	{
    206 		if (m_count)
    207 			*m_count += 1;
    208 	}
    209 
    210 	~RefCount (void)
    211 	{
    212 		if (m_count)
    213 			*m_count -= 1;
    214 	}
    215 
    216 	RefCount& operator= (const RefCount& other)
    217 	{
    218 		if (this == &other)
    219 			return *this;
    220 
    221 		if (m_count)
    222 			*m_count -= 1;
    223 
    224 		m_count = other.m_count;
    225 
    226 		if (m_count)
    227 			*m_count += 1;
    228 
    229 		return *this;
    230 	}
    231 
    232 private:
    233 	int* m_count;
    234 };
    235 
    236 } // anonymous
    237 
    238 static void sideEffectTest (void)
    239 {
    240 	MemPool				pool;
    241 	PoolArray<RefCount>	arr		(&pool);
    242 	int					count	= 0;
    243 	RefCount			counter	(&count);
    244 
    245 	DE_TEST_ASSERT(count == 1);
    246 
    247 	for (int i = 0; i < 127; i++)
    248 		arr.pushBack(counter);
    249 
    250 	DE_TEST_ASSERT(count == 128);
    251 
    252 	for (int i = 0; i < 10; i++)
    253 		arr.popBack();
    254 
    255 	DE_TEST_ASSERT(count == 118);
    256 
    257 	arr.resize(150);
    258 	DE_TEST_ASSERT(count == 118);
    259 
    260 	arr.resize(18);
    261 	DE_TEST_ASSERT(count == 19);
    262 
    263 	arr.resize(19);
    264 	DE_TEST_ASSERT(count == 19);
    265 
    266 	arr.clear();
    267 	DE_TEST_ASSERT(count == 1);
    268 }
    269 
    270 static void iteratorTest (void)
    271 {
    272 	MemPool			pool;
    273 	PoolArray<int>	arr		(&pool);
    274 
    275 	for (int ndx = 0; ndx < 128; ndx++)
    276 		arr.pushBack(ndx);
    277 
    278 	// ConstIterator
    279 	{
    280 		const PoolArray<int>& cRef = arr;
    281 		int ndx = 0;
    282 		for (PoolArray<int>::ConstIterator iter = cRef.begin(); iter != cRef.end(); iter++, ndx++)
    283 		{
    284 			DE_TEST_ASSERT(*iter == ndx);
    285 		}
    286 
    287 		// Cast & interop with non-const array.
    288 		ndx = 0;
    289 		for (PoolArray<int>::ConstIterator iter = arr.begin(); iter != arr.end(); iter++, ndx++)
    290 		{
    291 			DE_TEST_ASSERT(*iter == ndx);
    292 		}
    293 	}
    294 
    295 	// Arithmetics.
    296 	DE_TEST_ASSERT(arr.end()-arr.begin() == 128);
    297 	DE_TEST_ASSERT(*(arr.begin()+3) == 3);
    298 	DE_TEST_ASSERT(arr.begin()[4] == 4);
    299 
    300 	// Relational
    301 	DE_TEST_ASSERT(arr.begin() != arr.begin()+1);
    302 	DE_TEST_ASSERT(arr.begin() == arr.begin());
    303 	DE_TEST_ASSERT(arr.begin() != arr.end());
    304 	DE_TEST_ASSERT(arr.begin() < arr.end());
    305 	DE_TEST_ASSERT(arr.begin() < arr.begin()+1);
    306 	DE_TEST_ASSERT(arr.begin() <= arr.begin());
    307 	DE_TEST_ASSERT(arr.end() > arr.begin());
    308 	DE_TEST_ASSERT(arr.begin() >= arr.begin());
    309 
    310 	// Compatibility with stl.
    311 	DE_TEST_ASSERT(std::distance(arr.begin(), arr.end()) == 128);
    312 
    313 	std::vector<int> vecCopy(arr.size());
    314 	std::copy(arr.begin(), arr.end(), vecCopy.begin());
    315 	for (int ndx = 0; ndx < (int)vecCopy.size(); ndx++)
    316 		DE_TEST_ASSERT(vecCopy[ndx] == ndx);
    317 
    318 	std::fill(arr.begin(), arr.end(), -1);
    319 	for (int ndx = 0; ndx < (int)arr.size(); ndx++)
    320 		DE_TEST_ASSERT(arr[ndx] == -1);
    321 
    322 	std::copy(vecCopy.begin(), vecCopy.end(), arr.begin());
    323 	for (int ndx = 0; ndx < (int)arr.size(); ndx++)
    324 		DE_TEST_ASSERT(arr[ndx] == ndx);
    325 
    326 	// Iterator
    327 	{
    328 		int ndx = 0;
    329 		for (PoolArray<int>::Iterator iter = arr.begin(); iter != arr.end(); iter++, ndx++)
    330 		{
    331 			DE_TEST_ASSERT(*iter == ndx);
    332 			if (ndx == 4)
    333 				*iter = 0;
    334 			else if (ndx == 7)
    335 				*(iter-1) = 1;
    336 		}
    337 	}
    338 
    339 	DE_TEST_ASSERT(arr[4] == 0);
    340 	DE_TEST_ASSERT(arr[6] == 1);
    341 }
    342 
    343 void PoolArray_selfTest (void)
    344 {
    345 	intArrayTest();
    346 	alignedIntArrayTest();
    347 	sideEffectTest();
    348 	iteratorTest();
    349 }
    350 
    351 } // de
    352