mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
[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
This commit is contained in:
parent
70b58044ef
commit
efd63170c8
@ -921,6 +921,17 @@ public:
|
|||||||
SmallVectorImpl<T>::operator=(::std::move(RHS));
|
SmallVectorImpl<T>::operator=(::std::move(RHS));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) {
|
||||||
|
if (!RHS.empty())
|
||||||
|
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>
|
template<typename T, unsigned N>
|
||||||
|
@ -153,17 +153,14 @@ LLVM_ATTRIBUTE_USED void CompileTest() {
|
|||||||
V.resize(42);
|
V.resize(42);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test fixture class
|
class SmallVectorTestBase : public testing::Test {
|
||||||
template <typename VectorT>
|
|
||||||
class SmallVectorTest : public testing::Test {
|
|
||||||
protected:
|
protected:
|
||||||
VectorT theVector;
|
|
||||||
VectorT otherVector;
|
|
||||||
|
|
||||||
void SetUp() {
|
void SetUp() {
|
||||||
Constructable::reset();
|
Constructable::reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename VectorT>
|
||||||
void assertEmpty(VectorT & v) {
|
void assertEmpty(VectorT & v) {
|
||||||
// Size tests
|
// Size tests
|
||||||
EXPECT_EQ(0u, v.size());
|
EXPECT_EQ(0u, v.size());
|
||||||
@ -173,7 +170,8 @@ protected:
|
|||||||
EXPECT_TRUE(v.begin() == v.end());
|
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, ...) {
|
void assertValuesInOrder(VectorT & v, size_t size, ...) {
|
||||||
EXPECT_EQ(size, v.size());
|
EXPECT_EQ(size, v.size());
|
||||||
|
|
||||||
@ -188,6 +186,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a sequence of values to initialize the vector.
|
// Generate a sequence of values to initialize the vector.
|
||||||
|
template <typename VectorT>
|
||||||
void makeSequence(VectorT & v, int start, int end) {
|
void makeSequence(VectorT & v, int start, int end) {
|
||||||
for (int i = start; i <= end; ++i) {
|
for (int i = start; i <= end; ++i) {
|
||||||
v.push_back(Constructable(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>,
|
typedef ::testing::Types<SmallVector<Constructable, 0>,
|
||||||
SmallVector<Constructable, 1>,
|
SmallVector<Constructable, 1>,
|
||||||
SmallVector<Constructable, 2>,
|
SmallVector<Constructable, 2>,
|
||||||
@ -664,6 +672,67 @@ TYPED_TEST(SmallVectorTest, IteratorTest) {
|
|||||||
this->theVector.insert(this->theVector.end(), L.begin(), L.end());
|
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 {
|
struct notassignable {
|
||||||
int &x;
|
int &x;
|
||||||
notassignable(int &x) : x(x) {}
|
notassignable(int &x) : x(x) {}
|
||||||
|
Loading…
Reference in New Issue
Block a user