437 lines
10 KiB
C++
437 lines
10 KiB
C++
//
|
|
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
//
|
|
// FixedVector_unittest:
|
|
// Tests of the FastVector class
|
|
//
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "common/FastVector.h"
|
|
|
|
namespace angle
|
|
{
|
|
// Make sure the various constructors compile and do basic checks
|
|
TEST(FastVector, Constructors)
|
|
{
|
|
FastVector<int, 5> defaultContructor;
|
|
EXPECT_EQ(0u, defaultContructor.size());
|
|
|
|
// Try varying initial vector sizes to test purely stack-allocated and
|
|
// heap-allocated vectors, and ensure they copy correctly.
|
|
size_t vectorSizes[] = {5, 3, 16, 32};
|
|
|
|
for (size_t i = 0; i < sizeof(vectorSizes) / sizeof(vectorSizes[0]); i++)
|
|
{
|
|
FastVector<int, 5> count(vectorSizes[i]);
|
|
EXPECT_EQ(vectorSizes[i], count.size());
|
|
|
|
FastVector<int, 5> countAndValue(vectorSizes[i], 2);
|
|
EXPECT_EQ(vectorSizes[i], countAndValue.size());
|
|
EXPECT_EQ(2, countAndValue[1]);
|
|
|
|
FastVector<int, 5> copy(countAndValue);
|
|
EXPECT_EQ(copy, countAndValue);
|
|
|
|
FastVector<int, 5> copyRValue(std::move(count));
|
|
EXPECT_EQ(vectorSizes[i], copyRValue.size());
|
|
|
|
FastVector<int, 5> copyIter(countAndValue.begin(), countAndValue.end());
|
|
EXPECT_EQ(copyIter, countAndValue);
|
|
|
|
FastVector<int, 5> copyIterEmpty(countAndValue.begin(), countAndValue.begin());
|
|
EXPECT_TRUE(copyIterEmpty.empty());
|
|
|
|
FastVector<int, 5> assignCopy(copyRValue);
|
|
EXPECT_EQ(vectorSizes[i], assignCopy.size());
|
|
|
|
FastVector<int, 5> assignRValue(std::move(assignCopy));
|
|
EXPECT_EQ(vectorSizes[i], assignRValue.size());
|
|
}
|
|
|
|
FastVector<int, 5> initializerList{1, 2, 3, 4, 5};
|
|
EXPECT_EQ(5u, initializerList.size());
|
|
EXPECT_EQ(3, initializerList[2]);
|
|
|
|
// Larger than stack-allocated vector size
|
|
FastVector<int, 5> initializerListHeap{1, 2, 3, 4, 5, 6, 7, 8};
|
|
EXPECT_EQ(8u, initializerListHeap.size());
|
|
EXPECT_EQ(3, initializerListHeap[2]);
|
|
|
|
FastVector<int, 5> assignmentInitializerList = {1, 2, 3, 4, 5};
|
|
EXPECT_EQ(5u, assignmentInitializerList.size());
|
|
EXPECT_EQ(3, assignmentInitializerList[2]);
|
|
|
|
// Larger than stack-allocated vector size
|
|
FastVector<int, 5> assignmentInitializerListLarge = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
EXPECT_EQ(8u, assignmentInitializerListLarge.size());
|
|
EXPECT_EQ(3, assignmentInitializerListLarge[2]);
|
|
}
|
|
|
|
// Test indexing operations (at, operator[])
|
|
TEST(FastVector, Indexing)
|
|
{
|
|
FastVector<int, 5> vec = {0, 1, 2, 3, 4};
|
|
for (int i = 0; i < 5; ++i)
|
|
{
|
|
EXPECT_EQ(i, vec.at(i));
|
|
EXPECT_EQ(vec[i], vec.at(i));
|
|
}
|
|
}
|
|
|
|
// Test the push_back functions
|
|
TEST(FastVector, PushBack)
|
|
{
|
|
FastVector<int, 5> vec;
|
|
vec.push_back(1);
|
|
EXPECT_EQ(1, vec[0]);
|
|
vec.push_back(1);
|
|
vec.push_back(1);
|
|
vec.push_back(1);
|
|
vec.push_back(1);
|
|
EXPECT_EQ(5u, vec.size());
|
|
}
|
|
|
|
// Tests growing the fast vector beyond the fixed storage.
|
|
TEST(FastVector, Growth)
|
|
{
|
|
constexpr size_t kSize = 4;
|
|
FastVector<size_t, kSize> vec;
|
|
|
|
for (size_t i = 0; i < kSize * 2; ++i)
|
|
{
|
|
vec.push_back(i);
|
|
}
|
|
|
|
EXPECT_EQ(kSize * 2, vec.size());
|
|
|
|
for (size_t i = kSize * 2; i > 0; --i)
|
|
{
|
|
ASSERT_EQ(vec.back(), i - 1);
|
|
vec.pop_back();
|
|
}
|
|
|
|
EXPECT_EQ(0u, vec.size());
|
|
}
|
|
|
|
// Test the pop_back function
|
|
TEST(FastVector, PopBack)
|
|
{
|
|
FastVector<int, 5> vec;
|
|
vec.push_back(1);
|
|
EXPECT_EQ(1, (int)vec.size());
|
|
vec.pop_back();
|
|
EXPECT_EQ(0, (int)vec.size());
|
|
}
|
|
|
|
// Test the back function
|
|
TEST(FastVector, Back)
|
|
{
|
|
FastVector<int, 5> vec;
|
|
vec.push_back(1);
|
|
vec.push_back(2);
|
|
EXPECT_EQ(2, vec.back());
|
|
}
|
|
|
|
// Test the back function
|
|
TEST(FastVector, Front)
|
|
{
|
|
FastVector<int, 5> vec;
|
|
vec.push_back(1);
|
|
vec.push_back(2);
|
|
EXPECT_EQ(1, vec.front());
|
|
}
|
|
|
|
// Test the sizing operations
|
|
TEST(FastVector, Size)
|
|
{
|
|
FastVector<int, 5> vec;
|
|
EXPECT_TRUE(vec.empty());
|
|
EXPECT_EQ(0u, vec.size());
|
|
|
|
vec.push_back(1);
|
|
EXPECT_FALSE(vec.empty());
|
|
EXPECT_EQ(1u, vec.size());
|
|
}
|
|
|
|
// Test clearing the vector
|
|
TEST(FastVector, Clear)
|
|
{
|
|
FastVector<int, 5> vec = {0, 1, 2, 3, 4};
|
|
vec.clear();
|
|
EXPECT_TRUE(vec.empty());
|
|
}
|
|
|
|
// Test clearing the vector larger than the fixed size.
|
|
TEST(FastVector, ClearWithLargerThanFixedSize)
|
|
{
|
|
FastVector<int, 3> vec = {0, 1, 2, 3, 4};
|
|
vec.clear();
|
|
EXPECT_TRUE(vec.empty());
|
|
}
|
|
|
|
// Test resizing the vector
|
|
TEST(FastVector, Resize)
|
|
{
|
|
FastVector<int, 5> vec;
|
|
vec.resize(5u, 1);
|
|
EXPECT_EQ(5u, vec.size());
|
|
for (int i : vec)
|
|
{
|
|
EXPECT_EQ(1, i);
|
|
}
|
|
|
|
vec.resize(2u);
|
|
EXPECT_EQ(2u, vec.size());
|
|
for (int i : vec)
|
|
{
|
|
EXPECT_EQ(1, i);
|
|
}
|
|
|
|
// Resize to larger than minimum
|
|
vec.resize(10u, 2);
|
|
EXPECT_EQ(10u, vec.size());
|
|
|
|
for (size_t index = 0; index < 2u; ++index)
|
|
{
|
|
EXPECT_EQ(1, vec[index]);
|
|
}
|
|
for (size_t index = 2u; index < 10u; ++index)
|
|
{
|
|
EXPECT_EQ(2, vec[index]);
|
|
}
|
|
|
|
// Resize back to smaller
|
|
vec.resize(2u, 2);
|
|
EXPECT_EQ(2u, vec.size());
|
|
}
|
|
|
|
// Test iterating over the vector
|
|
TEST(FastVector, Iteration)
|
|
{
|
|
FastVector<int, 5> vec = {0, 1, 2, 3};
|
|
|
|
int vistedCount = 0;
|
|
for (int value : vec)
|
|
{
|
|
EXPECT_EQ(vistedCount, value);
|
|
vistedCount++;
|
|
}
|
|
EXPECT_EQ(4, vistedCount);
|
|
}
|
|
|
|
// Tests that equality comparisons work even if reserved size differs.
|
|
TEST(FastVector, EqualityWithDifferentReservedSizes)
|
|
{
|
|
FastVector<int, 3> vec1 = {1, 2, 3, 4, 5};
|
|
FastVector<int, 5> vec2 = {1, 2, 3, 4, 5};
|
|
EXPECT_EQ(vec1, vec2);
|
|
vec2.push_back(6);
|
|
EXPECT_NE(vec1, vec2);
|
|
}
|
|
|
|
// Tests vector operations with a non copyable type.
|
|
TEST(FastVector, NonCopyable)
|
|
{
|
|
struct s : angle::NonCopyable
|
|
{
|
|
s() : x(0) {}
|
|
s(int xin) : x(xin) {}
|
|
s(s &&other) : x(other.x) {}
|
|
s &operator=(s &&other)
|
|
{
|
|
x = other.x;
|
|
return *this;
|
|
}
|
|
int x;
|
|
};
|
|
|
|
FastVector<s, 3> vec;
|
|
vec.push_back(3);
|
|
EXPECT_EQ(3, vec[0].x);
|
|
|
|
FastVector<s, 3> copy = std::move(vec);
|
|
EXPECT_EQ(1u, copy.size());
|
|
EXPECT_EQ(3, copy[0].x);
|
|
}
|
|
|
|
// Basic functionality for FlatUnorderedMap
|
|
TEST(FlatUnorderedMap, BasicUsage)
|
|
{
|
|
FlatUnorderedMap<int, bool, 3> testMap;
|
|
EXPECT_TRUE(testMap.empty());
|
|
EXPECT_EQ(testMap.size(), 0u);
|
|
|
|
testMap.insert(5, true);
|
|
EXPECT_TRUE(testMap.contains(5));
|
|
EXPECT_EQ(testMap.size(), 1u);
|
|
|
|
bool value = false;
|
|
EXPECT_TRUE(testMap.get(5, &value));
|
|
EXPECT_TRUE(value);
|
|
EXPECT_FALSE(testMap.get(6, &value));
|
|
|
|
EXPECT_FALSE(testMap.empty());
|
|
testMap.clear();
|
|
EXPECT_TRUE(testMap.empty());
|
|
EXPECT_EQ(testMap.size(), 0u);
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
testMap.insert(i, false);
|
|
}
|
|
|
|
EXPECT_FALSE(testMap.empty());
|
|
EXPECT_EQ(testMap.size(), 10u);
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
EXPECT_TRUE(testMap.contains(i));
|
|
EXPECT_TRUE(testMap.get(i, &value));
|
|
EXPECT_FALSE(value);
|
|
}
|
|
}
|
|
|
|
// Basic functionality for FlatUnorderedSet
|
|
TEST(FlatUnorderedSet, BasicUsage)
|
|
{
|
|
FlatUnorderedSet<int, 3> testMap;
|
|
EXPECT_TRUE(testMap.empty());
|
|
|
|
testMap.insert(5);
|
|
EXPECT_TRUE(testMap.contains(5));
|
|
EXPECT_FALSE(testMap.contains(6));
|
|
EXPECT_FALSE(testMap.empty());
|
|
|
|
testMap.clear();
|
|
EXPECT_TRUE(testMap.empty());
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
testMap.insert(i);
|
|
}
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
EXPECT_TRUE(testMap.contains(i));
|
|
}
|
|
}
|
|
|
|
// Comparison of FlatUnorderedSet
|
|
TEST(FlatUnorderedSet, Comparison)
|
|
{
|
|
FlatUnorderedSet<int, 3> testSet0;
|
|
FlatUnorderedSet<int, 3> testSet1;
|
|
EXPECT_TRUE(testSet0.empty());
|
|
EXPECT_TRUE(testSet1.empty());
|
|
|
|
testSet0.insert(5);
|
|
EXPECT_FALSE(testSet0 == testSet1);
|
|
|
|
testSet0.insert(10);
|
|
EXPECT_FALSE(testSet0 == testSet1);
|
|
|
|
testSet1.insert(5);
|
|
EXPECT_FALSE(testSet0 == testSet1);
|
|
|
|
testSet1.insert(15);
|
|
EXPECT_FALSE(testSet0 == testSet1);
|
|
|
|
testSet1.clear();
|
|
testSet1.insert(5);
|
|
testSet1.insert(10);
|
|
EXPECT_TRUE(testSet0 == testSet1);
|
|
}
|
|
|
|
// Basic functionality for FastIntegerSet
|
|
TEST(FastIntegerSet, BasicUsage)
|
|
{
|
|
FastIntegerSet testMap;
|
|
EXPECT_TRUE(testMap.empty());
|
|
|
|
testMap.insert(5);
|
|
EXPECT_TRUE(testMap.contains(5));
|
|
EXPECT_FALSE(testMap.contains(6));
|
|
EXPECT_FALSE(testMap.empty());
|
|
|
|
testMap.clear();
|
|
EXPECT_TRUE(testMap.empty());
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
testMap.insert(i);
|
|
}
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
EXPECT_TRUE(testMap.contains(i));
|
|
}
|
|
}
|
|
|
|
// Basic functionality for FastIntegerMap
|
|
TEST(FastIntegerMap, BasicUsage)
|
|
{
|
|
using KeyValuePair = std::pair<int, std::string>;
|
|
std::set<KeyValuePair> entries = {KeyValuePair(17, "testing"), KeyValuePair(63, "fast"),
|
|
KeyValuePair(97, "integer"), KeyValuePair(256, "map")};
|
|
|
|
FastIntegerMap<std::string> testMap;
|
|
EXPECT_TRUE(testMap.empty());
|
|
|
|
std::string str;
|
|
testMap.insert(entries.begin()->first, entries.begin()->second);
|
|
EXPECT_TRUE(testMap.contains(entries.begin()->first));
|
|
EXPECT_FALSE(testMap.contains(entries.rbegin()->first));
|
|
EXPECT_FALSE(testMap.empty());
|
|
EXPECT_EQ(testMap.size(), 1u);
|
|
EXPECT_TRUE(testMap.get(entries.begin()->first, &str));
|
|
EXPECT_EQ(entries.begin()->second, str);
|
|
EXPECT_FALSE(testMap.get(1, &str));
|
|
|
|
testMap.clear();
|
|
EXPECT_TRUE(testMap.empty());
|
|
EXPECT_EQ(testMap.size(), 0u);
|
|
|
|
for (KeyValuePair entry : entries)
|
|
{
|
|
testMap.insert(entry.first, entry.second);
|
|
}
|
|
EXPECT_EQ(testMap.size(), 4u);
|
|
|
|
for (KeyValuePair entry : entries)
|
|
{
|
|
EXPECT_TRUE(testMap.get(entry.first, &str));
|
|
EXPECT_EQ(entry.second, str);
|
|
}
|
|
|
|
testMap.clear();
|
|
EXPECT_TRUE(testMap.empty());
|
|
EXPECT_EQ(testMap.size(), 0u);
|
|
}
|
|
|
|
// Basic usage tests of fast map.
|
|
TEST(FastMap, Basic)
|
|
{
|
|
FastMap<int, 5> testMap;
|
|
EXPECT_TRUE(testMap.empty());
|
|
|
|
testMap[5] = 5;
|
|
EXPECT_FALSE(testMap.empty());
|
|
|
|
testMap.clear();
|
|
EXPECT_TRUE(testMap.empty());
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
testMap[i] = i;
|
|
}
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
EXPECT_TRUE(testMap[i] == i);
|
|
}
|
|
}
|
|
} // namespace angle
|