From: Benjamin Kramer Date: Sat, 7 Feb 2015 16:41:02 +0000 (+0000) Subject: SmallVector: Move emplace_back to SmallVectorImpl. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=ff53b757ea15616d70f3bc85c3d8de1723b85179;p=oota-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228496 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index da4ac10c0ba..af9bbb62345 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -236,51 +236,6 @@ public: this->setEnd(this->end()-1); this->end()->~T(); } - -#if LLVM_HAS_VARIADIC_TEMPLATES - template void emplace_back(ArgTypes &&... Args) { - if (LLVM_UNLIKELY(this->EndX >= this->CapacityX)) - this->grow(); - ::new ((void *)this->end()) T(std::forward(Args)...); - this->setEnd(this->end() + 1); - } -#else -private: - template 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 void emplace_back(T1 &&A1) { - emplace_back_impl([&](void *Mem) { ::new (Mem) T(std::forward(A1)); }); - } - template void emplace_back(T1 &&A1, T2 &&A2) { - emplace_back_impl([&](void *Mem) { - ::new (Mem) T(std::forward(A1), std::forward(A2)); - }); - } - template - void emplace_back(T1 &&A1, T2 &&A2, T3 &&A3) { - T(std::forward(A1), std::forward(A2), std::forward(A3)); - emplace_back_impl([&](void *Mem) { - ::new (Mem) - T(std::forward(A1), std::forward(A2), std::forward(A3)); - }); - } - template - void emplace_back(T1 &&A1, T2 &&A2, T3 &&A3, T4 &&A4) { - emplace_back_impl([&](void *Mem) { - ::new (Mem) T(std::forward(A1), std::forward(A2), - std::forward(A3), std::forward(A4)); - }); - } -#endif // LLVM_HAS_VARIADIC_TEMPLATES }; // Define this out-of-line to dissuade the C++ compiler from inlining it. @@ -677,6 +632,51 @@ public: return I; } +#if LLVM_HAS_VARIADIC_TEMPLATES + template void emplace_back(ArgTypes &&... Args) { + if (LLVM_UNLIKELY(this->EndX >= this->CapacityX)) + this->grow(); + ::new ((void *)this->end()) T(std::forward(Args)...); + this->setEnd(this->end() + 1); + } +#else +private: + template 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 void emplace_back(T1 &&A1) { + emplace_back_impl([&](void *Mem) { ::new (Mem) T(std::forward(A1)); }); + } + template void emplace_back(T1 &&A1, T2 &&A2) { + emplace_back_impl([&](void *Mem) { + ::new (Mem) T(std::forward(A1), std::forward(A2)); + }); + } + template + void emplace_back(T1 &&A1, T2 &&A2, T3 &&A3) { + T(std::forward(A1), std::forward(A2), std::forward(A3)); + emplace_back_impl([&](void *Mem) { + ::new (Mem) + T(std::forward(A1), std::forward(A2), std::forward(A3)); + }); + } + template + void emplace_back(T1 &&A1, T2 &&A2, T3 &&A3, T4 &&A4) { + emplace_back_impl([&](void *Mem) { + ::new (Mem) T(std::forward(A1), std::forward(A2), + std::forward(A3), std::forward(A4)); + }); + } +#endif // LLVM_HAS_VARIADIC_TEMPLATES + SmallVectorImpl &operator=(const SmallVectorImpl &RHS); SmallVectorImpl &operator=(SmallVectorImpl &&RHS); diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp index f6e9bb965c6..170a30bbac6 100644 --- a/unittests/ADT/SmallVectorTest.cpp +++ b/unittests/ADT/SmallVectorTest.cpp @@ -896,6 +896,14 @@ TEST(SmallVectorTest, EmplaceBack) { EXPECT_TRUE(V.back().A2.State == EAS_RValue); EXPECT_TRUE(V.back().A3.State == EAS_LValue); } + { + SmallVector 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