// // 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 #include "common/FastVector.h" namespace angle { // Make sure the various constructors compile and do basic checks TEST(FastVector, Constructors) { FastVector 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 count(vectorSizes[i]); EXPECT_EQ(vectorSizes[i], count.size()); FastVector countAndValue(vectorSizes[i], 2); EXPECT_EQ(vectorSizes[i], countAndValue.size()); EXPECT_EQ(2, countAndValue[1]); FastVector copy(countAndValue); EXPECT_EQ(copy, countAndValue); FastVector copyRValue(std::move(count)); EXPECT_EQ(vectorSizes[i], copyRValue.size()); FastVector copyIter(countAndValue.begin(), countAndValue.end()); EXPECT_EQ(copyIter, countAndValue); FastVector copyIterEmpty(countAndValue.begin(), countAndValue.begin()); EXPECT_TRUE(copyIterEmpty.empty()); FastVector assignCopy(copyRValue); EXPECT_EQ(vectorSizes[i], assignCopy.size()); FastVector assignRValue(std::move(assignCopy)); EXPECT_EQ(vectorSizes[i], assignRValue.size()); } FastVector initializerList{1, 2, 3, 4, 5}; EXPECT_EQ(5u, initializerList.size()); EXPECT_EQ(3, initializerList[2]); // Larger than stack-allocated vector size FastVector initializerListHeap{1, 2, 3, 4, 5, 6, 7, 8}; EXPECT_EQ(8u, initializerListHeap.size()); EXPECT_EQ(3, initializerListHeap[2]); FastVector assignmentInitializerList = {1, 2, 3, 4, 5}; EXPECT_EQ(5u, assignmentInitializerList.size()); EXPECT_EQ(3, assignmentInitializerList[2]); // Larger than stack-allocated vector size FastVector 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 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 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 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 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 vec; vec.push_back(1); vec.push_back(2); EXPECT_EQ(2, vec.back()); } // Test the back function TEST(FastVector, Front) { FastVector vec; vec.push_back(1); vec.push_back(2); EXPECT_EQ(1, vec.front()); } // Test the sizing operations TEST(FastVector, Size) { FastVector 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 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 vec = {0, 1, 2, 3, 4}; vec.clear(); EXPECT_TRUE(vec.empty()); } // Test resizing the vector TEST(FastVector, Resize) { FastVector 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 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 vec1 = {1, 2, 3, 4, 5}; FastVector 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 vec; vec.push_back(3); EXPECT_EQ(3, vec[0].x); FastVector copy = std::move(vec); EXPECT_EQ(1u, copy.size()); EXPECT_EQ(3, copy[0].x); } // Basic functionality for FlatUnorderedMap TEST(FlatUnorderedMap, BasicUsage) { FlatUnorderedMap 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 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 testSet0; FlatUnorderedSet 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; std::set entries = {KeyValuePair(17, "testing"), KeyValuePair(63, "fast"), KeyValuePair(97, "integer"), KeyValuePair(256, "map")}; FastIntegerMap 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 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