llvm.org GIT mirror llvm / efd6317
[ADT] Add move operations to SmallVector<T,N> from SmallVectorImpl<T>. This makes it possible to move between SmallVectors of different sizes. Thanks to Dave Blaikie and Duncan Smith for patch feedback. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226899 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 5 years ago
2 changed file(s) with 86 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
920920 SmallVectorImpl::operator=(::std::move(RHS));
921921 return *this;
922922 }
923
924 SmallVector(SmallVectorImpl &&RHS) : SmallVectorImpl(N) {
925 if (!RHS.empty())
926 SmallVectorImpl::operator=(::std::move(RHS));
927 }
928
929 const SmallVector &operator=(SmallVectorImpl &&RHS) {
930 SmallVectorImpl::operator=(::std::move(RHS));
931 return *this;
932 }
933
923934 };
924935
925936 template
152152 V.resize(42);
153153 }
154154
155 // Test fixture class
156 template
157 class SmallVectorTest : public testing::Test {
155 class SmallVectorTestBase : public testing::Test {
158156 protected:
159 VectorT theVector;
160 VectorT otherVector;
161157
162158 void SetUp() {
163159 Constructable::reset();
164160 }
165161
162 template
166163 void assertEmpty(VectorT & v) {
167164 // Size tests
168165 EXPECT_EQ(0u, v.size());
172169 EXPECT_TRUE(v.begin() == v.end());
173170 }
174171
175 // Assert that theVector contains the specified values, in order.
172 // Assert that v contains the specified values, in order.
173 template
176174 void assertValuesInOrder(VectorT & v, size_t size, ...) {
177175 EXPECT_EQ(size, v.size());
178176
187185 }
188186
189187 // Generate a sequence of values to initialize the vector.
188 template
190189 void makeSequence(VectorT & v, int start, int end) {
191190 for (int i = start; i <= end; ++i) {
192191 v.push_back(Constructable(i));
193192 }
194193 }
195194 };
195
196 // Test fixture class
197 template
198 class SmallVectorTest : public SmallVectorTestBase {
199 protected:
200 VectorT theVector;
201 VectorT otherVector;
202 };
203
196204
197205 typedef ::testing::Types,
198206 SmallVector,
663671 this->theVector.insert(this->theVector.end(), L.begin(), L.end());
664672 }
665673
674 template class DualSmallVectorsTest;
675
676 template
677 class DualSmallVectorsTest> : public SmallVectorTestBase {
678 protected:
679 VectorT1 theVector;
680 VectorT2 otherVector;
681
682 template
683 static unsigned NumBuiltinElts(const SmallVector&) { return N; }
684 };
685
686 typedef ::testing::Types<
687 // Small mode -> Small mode.
688 std::pair, SmallVector>,
689 // Small mode -> Big mode.
690 std::pair, SmallVector>,
691 // Big mode -> Small mode.
692 std::pair, SmallVector>,
693 // Big mode -> Big mode.
694 std::pair, SmallVector>
695 > DualSmallVectorTestTypes;
696
697 TYPED_TEST_CASE(DualSmallVectorsTest, DualSmallVectorTestTypes);
698
699 TYPED_TEST(DualSmallVectorsTest, MoveAssignment) {
700 SCOPED_TRACE("MoveAssignTest-DualVectorTypes");
701
702 // Set up our vector with four elements.
703 for (unsigned I = 0; I < 4; ++I)
704 this->otherVector.push_back(Constructable(I));
705
706 const Constructable *OrigDataPtr = this->otherVector.data();
707
708 // Move-assign from the other vector.
709 this->theVector =
710 std::move(static_cast&>(this->otherVector));
711
712 // Make sure we have the right result.
713 this->assertValuesInOrder(this->theVector, 4u, 0, 1, 2, 3);
714
715 // Make sure the # of constructor/destructor calls line up. There
716 // are two live objects after clearing the other vector.
717 this->otherVector.clear();
718 EXPECT_EQ(Constructable::getNumConstructorCalls()-4,
719 Constructable::getNumDestructorCalls());
720
721 // If the source vector (otherVector) was in small-mode, assert that we just
722 // moved the data pointer over.
723 EXPECT_TRUE(this->NumBuiltinElts(this->otherVector) == 4 ||
724 this->theVector.data() == OrigDataPtr);
725
726 // There shouldn't be any live objects any more.
727 this->theVector.clear();
728 EXPECT_EQ(Constructable::getNumConstructorCalls(),
729 Constructable::getNumDestructorCalls());
730
731 // We shouldn't have copied anything in this whole process.
732 EXPECT_EQ(Constructable::getNumCopyConstructorCalls(), 0);
733 }
734
666735 struct notassignable {
667736 int &x;
668737 notassignable(int &x) : x(x) {}