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