[llvm] r228496 - SmallVector: Move emplace_back to SmallVectorImpl.

Benjamin Kramer benny.kra at googlemail.com
Sat Feb 7 08:41:02 PST 2015


Author: d0k
Date: Sat Feb  7 10:41:02 2015
New Revision: 228496

URL: http://llvm.org/viewvc/llvm-project?rev=228496&view=rev
Log:
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.

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=228496&r1=228495&r2=228496&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/SmallVector.h (original)
+++ llvm/trunk/include/llvm/ADT/SmallVector.h Sat Feb  7 10:41:02 2015
@@ -236,51 +236,6 @@ public:
     this->setEnd(this->end()-1);
     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.
@@ -677,6 +632,51 @@ public:
     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=(SmallVectorImpl &&RHS);

Modified: llvm/trunk/unittests/ADT/SmallVectorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/SmallVectorTest.cpp?rev=228496&r1=228495&r2=228496&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/SmallVectorTest.cpp (original)
+++ llvm/trunk/unittests/ADT/SmallVectorTest.cpp Sat Feb  7 10:41:02 2015
@@ -896,6 +896,14 @@ TEST(SmallVectorTest, EmplaceBack) {
     EXPECT_TRUE(V.back().A2.State == EAS_RValue);
     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





More information about the llvm-commits mailing list