SmallVector: Move emplace_back to SmallVectorImpl.
This resolves the strange effect that emplace_back is only available when the type contained in the vector is not trivially copyable. llvm-svn: 228496
This commit is contained in:
parent
0238b96c06
commit
1d563f40da
|
@ -236,51 +236,6 @@ public:
|
||||||
this->setEnd(this->end()-1);
|
this->setEnd(this->end()-1);
|
||||||
this->end()->~T();
|
this->end()->~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_HAS_VARIADIC_TEMPLATES
|
|
||||||
template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) {
|
|
||||||
if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
|
|
||||||
this->grow();
|
|
||||||
::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
|
|
||||||
this->setEnd(this->end() + 1);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
private:
|
|
||||||
template <typename Constructor> void emplace_back_impl(Constructor construct) {
|
|
||||||
if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
|
|
||||||
this->grow();
|
|
||||||
construct((void *)this->end());
|
|
||||||
this->setEnd(this->end() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
void emplace_back() {
|
|
||||||
emplace_back_impl([](void *Mem) { ::new (Mem) T(); });
|
|
||||||
}
|
|
||||||
template <typename T1> void emplace_back(T1 &&A1) {
|
|
||||||
emplace_back_impl([&](void *Mem) { ::new (Mem) T(std::forward<T1>(A1)); });
|
|
||||||
}
|
|
||||||
template <typename T1, typename T2> void emplace_back(T1 &&A1, T2 &&A2) {
|
|
||||||
emplace_back_impl([&](void *Mem) {
|
|
||||||
::new (Mem) T(std::forward<T1>(A1), std::forward<T2>(A2));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
template <typename T1, typename T2, typename T3>
|
|
||||||
void emplace_back(T1 &&A1, T2 &&A2, T3 &&A3) {
|
|
||||||
T(std::forward<T1>(A1), std::forward<T2>(A2), std::forward<T3>(A3));
|
|
||||||
emplace_back_impl([&](void *Mem) {
|
|
||||||
::new (Mem)
|
|
||||||
T(std::forward<T1>(A1), std::forward<T2>(A2), std::forward<T3>(A3));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4>
|
|
||||||
void emplace_back(T1 &&A1, T2 &&A2, T3 &&A3, T4 &&A4) {
|
|
||||||
emplace_back_impl([&](void *Mem) {
|
|
||||||
::new (Mem) T(std::forward<T1>(A1), std::forward<T2>(A2),
|
|
||||||
std::forward<T3>(A3), std::forward<T4>(A4));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#endif // LLVM_HAS_VARIADIC_TEMPLATES
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define this out-of-line to dissuade the C++ compiler from inlining it.
|
// Define this out-of-line to dissuade the C++ compiler from inlining it.
|
||||||
|
@ -677,6 +632,51 @@ public:
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LLVM_HAS_VARIADIC_TEMPLATES
|
||||||
|
template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) {
|
||||||
|
if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
|
||||||
|
this->grow();
|
||||||
|
::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
|
||||||
|
this->setEnd(this->end() + 1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
private:
|
||||||
|
template <typename Constructor> void emplace_back_impl(Constructor construct) {
|
||||||
|
if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
|
||||||
|
this->grow();
|
||||||
|
construct((void *)this->end());
|
||||||
|
this->setEnd(this->end() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void emplace_back() {
|
||||||
|
emplace_back_impl([](void *Mem) { ::new (Mem) T(); });
|
||||||
|
}
|
||||||
|
template <typename T1> void emplace_back(T1 &&A1) {
|
||||||
|
emplace_back_impl([&](void *Mem) { ::new (Mem) T(std::forward<T1>(A1)); });
|
||||||
|
}
|
||||||
|
template <typename T1, typename T2> void emplace_back(T1 &&A1, T2 &&A2) {
|
||||||
|
emplace_back_impl([&](void *Mem) {
|
||||||
|
::new (Mem) T(std::forward<T1>(A1), std::forward<T2>(A2));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
template <typename T1, typename T2, typename T3>
|
||||||
|
void emplace_back(T1 &&A1, T2 &&A2, T3 &&A3) {
|
||||||
|
T(std::forward<T1>(A1), std::forward<T2>(A2), std::forward<T3>(A3));
|
||||||
|
emplace_back_impl([&](void *Mem) {
|
||||||
|
::new (Mem)
|
||||||
|
T(std::forward<T1>(A1), std::forward<T2>(A2), std::forward<T3>(A3));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
template <typename T1, typename T2, typename T3, typename T4>
|
||||||
|
void emplace_back(T1 &&A1, T2 &&A2, T3 &&A3, T4 &&A4) {
|
||||||
|
emplace_back_impl([&](void *Mem) {
|
||||||
|
::new (Mem) T(std::forward<T1>(A1), std::forward<T2>(A2),
|
||||||
|
std::forward<T3>(A3), std::forward<T4>(A4));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif // LLVM_HAS_VARIADIC_TEMPLATES
|
||||||
|
|
||||||
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
|
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
|
||||||
|
|
||||||
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
|
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
|
||||||
|
|
|
@ -896,6 +896,14 @@ TEST(SmallVectorTest, EmplaceBack) {
|
||||||
EXPECT_TRUE(V.back().A2.State == EAS_RValue);
|
EXPECT_TRUE(V.back().A2.State == EAS_RValue);
|
||||||
EXPECT_TRUE(V.back().A3.State == EAS_LValue);
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
Loading…
Reference in New Issue