/*------------------------------------------------------------------------- * drawElements C++ Base Library * ----------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Array template backed by memory pool. *//*--------------------------------------------------------------------*/ #include "dePoolArray.hpp" #include <algorithm> #include <vector> namespace de { static void intArrayTest (void) { MemPool pool; PoolArray<int> arr (&pool); PoolArray<deUint16> arr16 (&pool); int i; /* Test pushBack(). */ for (i = 0; i < 5000; i++) { /* Dummy alloc to try to break alignments. */ pool.alloc(1); arr.pushBack(i); arr16.pushBack((deInt16)i); } DE_TEST_ASSERT(arr.size() == 5000); DE_TEST_ASSERT(arr16.size() == 5000); for (i = 0; i < 5000; i++) { DE_TEST_ASSERT(arr[i] == i); DE_TEST_ASSERT(arr16[i] == i); } /* Test popBack(). */ for (i = 0; i < 1000; i++) { DE_TEST_ASSERT(arr.popBack() == (4999 - i)); DE_TEST_ASSERT(arr16.popBack() == (4999 - i)); } DE_TEST_ASSERT(arr.size() == 4000); DE_TEST_ASSERT(arr16.size() == 4000); for (i = 0; i < 4000; i++) { DE_TEST_ASSERT(arr[i] == i); DE_TEST_ASSERT(arr16[i] == i); } /* Test resize(). */ arr.resize(1000); arr16.resize(1000); for (i = 1000; i < 5000; i++) { arr.pushBack(i); arr16.pushBack((deInt16)i); } DE_TEST_ASSERT(arr.size() == 5000); DE_TEST_ASSERT(arr16.size() == 5000); for (i = 0; i < 5000; i++) { DE_TEST_ASSERT(arr[i] == i); DE_TEST_ASSERT(arr16[i] == i); } /* Test set() and pushBack() with reserve(). */ PoolArray<int> arr2(&pool); arr2.resize(1500); arr2.reserve(2000); for (i = 0; i < 1500; i++) arr2[i] = i; for (; i < 5000; i++) arr2.pushBack(i); DE_TEST_ASSERT(arr2.size() == 5000); for (i = 0; i < 5000; i++) { int val = arr2[i]; DE_TEST_ASSERT(val == i); } } static void alignedIntArrayTest (void) { MemPool pool; PoolArray<int, 16> arr (&pool); PoolArray<deUint16, 8> arr16 (&pool); int i; /* Test pushBack(). */ for (i = 0; i < 5000; i++) { /* Dummy alloc to try to break alignments. */ pool.alloc(1); arr.pushBack(i); arr16.pushBack((deInt16)i); } DE_TEST_ASSERT(arr.size() == 5000); DE_TEST_ASSERT(arr16.size() == 5000); for (i = 0; i < 5000; i++) { DE_TEST_ASSERT(arr[i] == i); DE_TEST_ASSERT(arr16[i] == i); } /* Test popBack(). */ for (i = 0; i < 1000; i++) { DE_TEST_ASSERT(arr.popBack() == (4999 - i)); DE_TEST_ASSERT(arr16.popBack() == (4999 - i)); } DE_TEST_ASSERT(arr.size() == 4000); DE_TEST_ASSERT(arr16.size() == 4000); for (i = 0; i < 4000; i++) { DE_TEST_ASSERT(arr[i] == i); DE_TEST_ASSERT(arr16[i] == i); } /* Test resize(). */ arr.resize(1000); arr16.resize(1000); for (i = 1000; i < 5000; i++) { arr.pushBack(i); arr16.pushBack((deInt16)i); } DE_TEST_ASSERT(arr.size() == 5000); DE_TEST_ASSERT(arr16.size() == 5000); for (i = 0; i < 5000; i++) { DE_TEST_ASSERT(arr[i] == i); DE_TEST_ASSERT(arr16[i] == i); } arr.resize(0); arr.resize(100, -123); DE_TEST_ASSERT(arr.size() == 100); for (i = 0; i < 100; i++) DE_TEST_ASSERT(arr[i] == -123); /* Test set() and pushBack() with reserve(). */ PoolArray<int, 32> arr2(&pool); arr2.resize(1500); arr2.reserve(2000); for (i = 0; i < 1500; i++) arr2[i] = i; for (; i < 5000; i++) arr2.pushBack(i); DE_TEST_ASSERT(arr2.size() == 5000); for (i = 0; i < 5000; i++) { int val = arr2[i]; DE_TEST_ASSERT(val == i); } } namespace { class RefCount { public: RefCount (void) : m_count(DE_NULL) { } RefCount (int* count) : m_count(count) { *m_count += 1; } RefCount (const RefCount& other) : m_count(other.m_count) { if (m_count) *m_count += 1; } ~RefCount (void) { if (m_count) *m_count -= 1; } RefCount& operator= (const RefCount& other) { if (this == &other) return *this; if (m_count) *m_count -= 1; m_count = other.m_count; if (m_count) *m_count += 1; return *this; } private: int* m_count; }; } // anonymous static void sideEffectTest (void) { MemPool pool; PoolArray<RefCount> arr (&pool); int count = 0; RefCount counter (&count); DE_TEST_ASSERT(count == 1); for (int i = 0; i < 127; i++) arr.pushBack(counter); DE_TEST_ASSERT(count == 128); for (int i = 0; i < 10; i++) arr.popBack(); DE_TEST_ASSERT(count == 118); arr.resize(150); DE_TEST_ASSERT(count == 118); arr.resize(18); DE_TEST_ASSERT(count == 19); arr.resize(19); DE_TEST_ASSERT(count == 19); arr.clear(); DE_TEST_ASSERT(count == 1); } static void iteratorTest (void) { MemPool pool; PoolArray<int> arr (&pool); for (int ndx = 0; ndx < 128; ndx++) arr.pushBack(ndx); // ConstIterator { const PoolArray<int>& cRef = arr; int ndx = 0; for (PoolArray<int>::ConstIterator iter = cRef.begin(); iter != cRef.end(); iter++, ndx++) { DE_TEST_ASSERT(*iter == ndx); } // Cast & interop with non-const array. ndx = 0; for (PoolArray<int>::ConstIterator iter = arr.begin(); iter != arr.end(); iter++, ndx++) { DE_TEST_ASSERT(*iter == ndx); } } // Arithmetics. DE_TEST_ASSERT(arr.end()-arr.begin() == 128); DE_TEST_ASSERT(*(arr.begin()+3) == 3); DE_TEST_ASSERT(arr.begin()[4] == 4); // Relational DE_TEST_ASSERT(arr.begin() != arr.begin()+1); DE_TEST_ASSERT(arr.begin() == arr.begin()); DE_TEST_ASSERT(arr.begin() != arr.end()); DE_TEST_ASSERT(arr.begin() < arr.end()); DE_TEST_ASSERT(arr.begin() < arr.begin()+1); DE_TEST_ASSERT(arr.begin() <= arr.begin()); DE_TEST_ASSERT(arr.end() > arr.begin()); DE_TEST_ASSERT(arr.begin() >= arr.begin()); // Compatibility with stl. DE_TEST_ASSERT(std::distance(arr.begin(), arr.end()) == 128); std::vector<int> vecCopy(arr.size()); std::copy(arr.begin(), arr.end(), vecCopy.begin()); for (int ndx = 0; ndx < (int)vecCopy.size(); ndx++) DE_TEST_ASSERT(vecCopy[ndx] == ndx); std::fill(arr.begin(), arr.end(), -1); for (int ndx = 0; ndx < (int)arr.size(); ndx++) DE_TEST_ASSERT(arr[ndx] == -1); std::copy(vecCopy.begin(), vecCopy.end(), arr.begin()); for (int ndx = 0; ndx < (int)arr.size(); ndx++) DE_TEST_ASSERT(arr[ndx] == ndx); // Iterator { int ndx = 0; for (PoolArray<int>::Iterator iter = arr.begin(); iter != arr.end(); iter++, ndx++) { DE_TEST_ASSERT(*iter == ndx); if (ndx == 4) *iter = 0; else if (ndx == 7) *(iter-1) = 1; } } DE_TEST_ASSERT(arr[4] == 0); DE_TEST_ASSERT(arr[6] == 1); } void PoolArray_selfTest (void) { intArrayTest(); alignedIntArrayTest(); sideEffectTest(); iteratorTest(); } } // de