diff options
Diffstat (limited to 'unittests/ADT/SmallVectorTest.cpp')
-rw-r--r-- | unittests/ADT/SmallVectorTest.cpp | 125 |
1 files changed, 109 insertions, 16 deletions
diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp index ba6c395e69fa1..46f7021ac165d 100644 --- a/unittests/ADT/SmallVectorTest.cpp +++ b/unittests/ADT/SmallVectorTest.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "gtest/gtest.h" @@ -144,8 +145,8 @@ struct NonCopyable { NonCopyable(NonCopyable &&) {} NonCopyable &operator=(NonCopyable &&) { return *this; } private: - NonCopyable(const NonCopyable &) LLVM_DELETED_FUNCTION; - NonCopyable &operator=(const NonCopyable &) LLVM_DELETED_FUNCTION; + NonCopyable(const NonCopyable &) = delete; + NonCopyable &operator=(const NonCopyable &) = delete; }; LLVM_ATTRIBUTE_USED void CompileTest() { @@ -153,17 +154,11 @@ LLVM_ATTRIBUTE_USED void CompileTest() { V.resize(42); } -// Test fixture class -template <typename VectorT> -class SmallVectorTest : public testing::Test { +class SmallVectorTestBase : public testing::Test { protected: - VectorT theVector; - VectorT otherVector; - - void SetUp() { - Constructable::reset(); - } + void SetUp() override { Constructable::reset(); } + template <typename VectorT> void assertEmpty(VectorT & v) { // Size tests EXPECT_EQ(0u, v.size()); @@ -173,7 +168,8 @@ protected: EXPECT_TRUE(v.begin() == v.end()); } - // Assert that theVector contains the specified values, in order. + // Assert that v contains the specified values, in order. + template <typename VectorT> void assertValuesInOrder(VectorT & v, size_t size, ...) { EXPECT_EQ(size, v.size()); @@ -188,6 +184,7 @@ protected: } // Generate a sequence of values to initialize the vector. + template <typename VectorT> void makeSequence(VectorT & v, int start, int end) { for (int i = start; i <= end; ++i) { v.push_back(Constructable(i)); @@ -195,6 +192,15 @@ protected: } }; +// Test fixture class +template <typename VectorT> +class SmallVectorTest : public SmallVectorTestBase { +protected: + VectorT theVector; + VectorT otherVector; +}; + + typedef ::testing::Types<SmallVector<Constructable, 0>, SmallVector<Constructable, 1>, SmallVector<Constructable, 2>, @@ -664,6 +670,67 @@ TYPED_TEST(SmallVectorTest, IteratorTest) { this->theVector.insert(this->theVector.end(), L.begin(), L.end()); } +template <typename InvalidType> class DualSmallVectorsTest; + +template <typename VectorT1, typename VectorT2> +class DualSmallVectorsTest<std::pair<VectorT1, VectorT2>> : public SmallVectorTestBase { +protected: + VectorT1 theVector; + VectorT2 otherVector; + + template <typename T, unsigned N> + static unsigned NumBuiltinElts(const SmallVector<T, N>&) { return N; } +}; + +typedef ::testing::Types< + // Small mode -> Small mode. + std::pair<SmallVector<Constructable, 4>, SmallVector<Constructable, 4>>, + // Small mode -> Big mode. + std::pair<SmallVector<Constructable, 4>, SmallVector<Constructable, 2>>, + // Big mode -> Small mode. + std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 4>>, + // Big mode -> Big mode. + std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 2>> + > DualSmallVectorTestTypes; + +TYPED_TEST_CASE(DualSmallVectorsTest, DualSmallVectorTestTypes); + +TYPED_TEST(DualSmallVectorsTest, MoveAssignment) { + SCOPED_TRACE("MoveAssignTest-DualVectorTypes"); + + // Set up our vector with four elements. + for (unsigned I = 0; I < 4; ++I) + this->otherVector.push_back(Constructable(I)); + + const Constructable *OrigDataPtr = this->otherVector.data(); + + // Move-assign from the other vector. + this->theVector = + std::move(static_cast<SmallVectorImpl<Constructable>&>(this->otherVector)); + + // Make sure we have the right result. + this->assertValuesInOrder(this->theVector, 4u, 0, 1, 2, 3); + + // Make sure the # of constructor/destructor calls line up. There + // are two live objects after clearing the other vector. + this->otherVector.clear(); + EXPECT_EQ(Constructable::getNumConstructorCalls()-4, + Constructable::getNumDestructorCalls()); + + // If the source vector (otherVector) was in small-mode, assert that we just + // moved the data pointer over. + EXPECT_TRUE(this->NumBuiltinElts(this->otherVector) == 4 || + this->theVector.data() == OrigDataPtr); + + // There shouldn't be any live objects any more. + this->theVector.clear(); + EXPECT_EQ(Constructable::getNumConstructorCalls(), + Constructable::getNumDestructorCalls()); + + // We shouldn't have copied anything in this whole process. + EXPECT_EQ(Constructable::getNumCopyConstructorCalls(), 0); +} + struct notassignable { int &x; notassignable(int &x) : x(x) {} @@ -717,8 +784,8 @@ template <int I> struct EmplaceableArg { explicit EmplaceableArg(bool) : State(EAS_Arg) {} private: - EmplaceableArg &operator=(EmplaceableArg &&) LLVM_DELETED_FUNCTION; - EmplaceableArg &operator=(const EmplaceableArg &) LLVM_DELETED_FUNCTION; + EmplaceableArg &operator=(EmplaceableArg &&) = delete; + EmplaceableArg &operator=(const EmplaceableArg &) = delete; }; enum EmplaceableState { ES_Emplaced, ES_Moved }; @@ -758,8 +825,8 @@ struct Emplaceable { } private: - Emplaceable(const Emplaceable &) LLVM_DELETED_FUNCTION; - Emplaceable &operator=(const Emplaceable &) LLVM_DELETED_FUNCTION; + Emplaceable(const Emplaceable &) = delete; + Emplaceable &operator=(const Emplaceable &) = delete; }; TEST(SmallVectorTest, EmplaceBack) { @@ -827,6 +894,32 @@ TEST(SmallVectorTest, EmplaceBack) { EXPECT_TRUE(V.back().A2.State == EAS_RValue); EXPECT_TRUE(V.back().A3.State == EAS_LValue); } + { + SmallVector<int, 1> V; + V.emplace_back(); + V.emplace_back(42); + EXPECT_EQ(2U, V.size()); + EXPECT_EQ(0, V[0]); + EXPECT_EQ(42, V[1]); + } +} + +TEST(SmallVectorTest, InitializerList) { + SmallVector<int, 2> V1 = {}; + EXPECT_TRUE(V1.empty()); + V1 = {0, 0}; + EXPECT_TRUE(makeArrayRef(V1).equals({0, 0})); + V1 = {-1, -1}; + EXPECT_TRUE(makeArrayRef(V1).equals({-1, -1})); + + SmallVector<int, 2> V2 = {1, 2, 3, 4}; + EXPECT_TRUE(makeArrayRef(V2).equals({1, 2, 3, 4})); + V2.assign({4}); + EXPECT_TRUE(makeArrayRef(V2).equals({4})); + V2.append({3, 2}); + EXPECT_TRUE(makeArrayRef(V2).equals({4, 3, 2})); + V2.insert(V2.begin() + 1, 5); + EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2})); } } // end namespace |