| // | |
| // 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()); | |
| FastVector<int, 5> count(3); | |
| EXPECT_EQ(3u, count.size()); | |
| FastVector<int, 5> countAndValue(3, 2); | |
| EXPECT_EQ(3u, 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(3u, 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> initializerList{1, 2, 3, 4, 5}; | |
| EXPECT_EQ(5u, initializerList.size()); | |
| EXPECT_EQ(3, initializerList[2]); | |
| FastVector<int, 5> assignCopy(copyRValue); | |
| EXPECT_EQ(3u, assignCopy.size()); | |
| FastVector<int, 5> assignRValue(std::move(assignCopy)); | |
| EXPECT_EQ(3u, assignRValue.size()); | |
| FastVector<int, 5> assignmentInitializerList = {1, 2, 3, 4, 5}; | |
| EXPECT_EQ(5u, assignmentInitializerList.size()); | |
| EXPECT_EQ(3, assignmentInitializerList[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 FastUnorderedMap | |
| TEST(FastUnorderedMap, BasicUsage) | |
| { | |
| FastUnorderedMap<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 FastUnorderedSet | |
| TEST(FastUnorderedSet, BasicUsage) | |
| { | |
| FastUnorderedSet<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)); | |
| } | |
| } | |
| // 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) | |
| { | |
| std::string str; | |
| EXPECT_TRUE(testMap.get(entry.first, &str)); | |
| EXPECT_EQ(entry.second, str); | |
| } | |
| testMap.clear(); | |
| EXPECT_TRUE(testMap.empty()); | |
| EXPECT_EQ(testMap.size(), 0u); | |
| } | |
| } // namespace angle |