[llvm] r226899 - [ADT] Add move operations to SmallVector<T, N> from SmallVectorImpl<T>.

David Blaikie dblaikie at gmail.com
Fri Jan 23 00:02:38 PST 2015


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/71f638d8/attachment.html>


More information about the llvm-commits mailing list