diff options
Diffstat (limited to 'include/llvm/ADT/SmallVector.h')
-rw-r--r-- | include/llvm/ADT/SmallVector.h | 98 |
1 files changed, 47 insertions, 51 deletions
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 44a352119b09c..5b208b76a21fa 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -24,6 +24,7 @@ #include <cstddef> #include <cstdlib> #include <cstring> +#include <initializer_list> #include <iterator> #include <memory> @@ -236,51 +237,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. @@ -352,8 +308,11 @@ protected: /// Copy the range [I, E) onto the uninitialized memory /// starting with "Dest", constructing elements into it as needed. - template<typename T1, typename T2> - static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) { + template <typename T1, typename T2> + static void uninitialized_copy( + T1 *I, T1 *E, T2 *Dest, + typename std::enable_if<std::is_same<typename std::remove_const<T1>::type, + T2>::value>::type * = nullptr) { // Use memcpy for PODs iterated by pointers (which includes SmallVector // iterators): std::uninitialized_copy optimizes to memmove, but we can // use memcpy here. @@ -385,7 +344,7 @@ template <typename T> class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> { typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass; - SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION; + SmallVectorImpl(const SmallVectorImpl&) = delete; public: typedef typename SuperClass::iterator iterator; typedef typename SuperClass::size_type size_type; @@ -459,9 +418,7 @@ public: this->grow(this->size()+NumInputs); // Copy the new elements over. - // TODO: NEED To compile time dispatch on whether in_iter is a random access - // iterator to use the fast uninitialized_copy. - std::uninitialized_copy(in_start, in_end, this->end()); + this->uninitialized_copy(in_start, in_end, this->end()); this->setEnd(this->end() + NumInputs); } @@ -476,6 +433,10 @@ public: this->setEnd(this->end() + NumInputs); } + void append(std::initializer_list<T> IL) { + append(IL.begin(), IL.end()); + } + void assign(size_type NumElts, const T &Elt) { clear(); if (this->capacity() < NumElts) @@ -484,6 +445,11 @@ public: std::uninitialized_fill(this->begin(), this->end(), Elt); } + void assign(std::initializer_list<T> IL) { + clear(); + append(IL); + } + iterator erase(iterator I) { assert(I >= this->begin() && "Iterator to erase is out of bounds."); assert(I < this->end() && "Erasing at past-the-end iterator."); @@ -677,6 +643,17 @@ public: return I; } + void insert(iterator I, std::initializer_list<T> IL) { + insert(I, IL.begin(), IL.end()); + } + + 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); + } + SmallVectorImpl &operator=(const SmallVectorImpl &RHS); SmallVectorImpl &operator=(SmallVectorImpl &&RHS); @@ -902,6 +879,10 @@ public: this->append(R.begin(), R.end()); } + SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) { + this->assign(IL); + } + SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) { if (!RHS.empty()) SmallVectorImpl<T>::operator=(RHS); @@ -921,6 +902,21 @@ public: SmallVectorImpl<T>::operator=(::std::move(RHS)); 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; + } + + const SmallVector &operator=(std::initializer_list<T> IL) { + this->assign(IL); + return *this; + } }; template<typename T, unsigned N> |