[llvm] r226899 - [ADT] Add move operations to SmallVector<T, N> from SmallVectorImpl<T>.
Lang Hames
lhames at gmail.com
Fri Jan 23 10:57:11 PST 2015
Hi Dave,
I didn't delve into the code to check, I just cribbed from the existing
implementations. My inclination is that that check should be pushed down
into SmallVectorImpl's methods though.
- Lang.
On Fri, Jan 23, 2015 at 12:02 AM, David Blaikie <dblaikie at gmail.com> wrote:
>
>
> On Thu, Jan 22, 2015 at 10:25 PM, Lang Hames <lhames at gmail.com> wrote:
>
>> Author: lhames
>> Date: Fri Jan 23 00:25:17 2015
>> New Revision: 226899
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=226899&view=rev
>> Log:
>> [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.
>>
>> Modified:
>> llvm/trunk/include/llvm/ADT/SmallVector.h
>> llvm/trunk/unittests/ADT/SmallVectorTest.cpp
>>
>> Modified: llvm/trunk/include/llvm/ADT/SmallVector.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallVector.h?rev=226899&r1=226898&r2=226899&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ADT/SmallVector.h (original)
>> +++ llvm/trunk/include/llvm/ADT/SmallVector.h Fri Jan 23 00:25:17 2015
>> @@ -921,6 +921,17 @@ public:
>> SmallVectorImpl<T>::operator=(::std::move(RHS));
>> return *this;
>> }
>> +
>> + SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) {
>> + if (!RHS.empty())
>>
>
> Is this ^ check necessary/useful for some reason? (why in the ctor, but
> not in the assignment operator?)
>
>
>> + SmallVectorImpl<T>::operator=(::std::move(RHS));
>> + }
>> +
>> + const SmallVector &operator=(SmallVectorImpl<T> &&RHS) {
>> + SmallVectorImpl<T>::operator=(::std::move(RHS));
>> + return *this;
>> + }
>> +
>> };
>>
>> template<typename T, unsigned N>
>>
>> Modified: llvm/trunk/unittests/ADT/SmallVectorTest.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/SmallVectorTest.cpp?rev=226899&r1=226898&r2=226899&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/unittests/ADT/SmallVectorTest.cpp (original)
>> +++ llvm/trunk/unittests/ADT/SmallVectorTest.cpp Fri Jan 23 00:25:17 2015
>> @@ -153,17 +153,14 @@ 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();
>> }
>>
>> + template <typename VectorT>
>> void assertEmpty(VectorT & v) {
>> // Size tests
>> EXPECT_EQ(0u, v.size());
>> @@ -173,7 +170,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 +186,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 +194,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 +672,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) {}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150123/24946b5f/attachment.html>
More information about the llvm-commits
mailing list