352 lines
7.0 KiB
C++
352 lines
7.0 KiB
C++
/*-------------------------------------------------------------------------
|
|
* 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++)
|
|
{
|
|
/* Unused 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++)
|
|
{
|
|
/* Unused 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
|