X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FSmallVector.h;h=d1062acbbb615bccc2564084e38ca85600466198;hb=44fb5881d8edf448d6231a5b8df583aecd6bcd42;hp=44a352119b09c82e07549428d8f45ee93660f91a;hpb=8a19eb2a85d42f6976b57a7b5c1ec6fb6b8a88c7;p=oota-llvm.git diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 44a352119b0..d1062acbbb6 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -108,9 +109,13 @@ public: typedef const T *const_pointer; // forward iterator creation methods. + LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin() { return (iterator)this->BeginX; } + LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator begin() const { return (const_iterator)this->BeginX; } + LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end() { return (iterator)this->EndX; } + LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator end() const { return (const_iterator)this->EndX; } protected: iterator capacity_ptr() { return (iterator)this->CapacityX; } @@ -123,6 +128,7 @@ public: reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin());} + LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const { return end()-begin(); } size_type max_size() const { return size_type(-1) / sizeof(T); } @@ -134,10 +140,12 @@ public: /// Return a pointer to the vector's buffer, even if empty(). const_pointer data() const { return const_pointer(begin()); } + LLVM_ATTRIBUTE_ALWAYS_INLINE reference operator[](size_type idx) { assert(idx < size()); return begin()[idx]; } + LLVM_ATTRIBUTE_ALWAYS_INLINE const_reference operator[](size_type idx) const { assert(idx < size()); return begin()[idx]; @@ -236,51 +244,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. @@ -352,12 +315,17 @@ protected: /// Copy the range [I, E) onto the uninitialized memory /// starting with "Dest", constructing elements into it as needed. - template - static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) { + template + static void uninitialized_copy( + T1 *I, T1 *E, T2 *Dest, + typename std::enable_if::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. - memcpy(Dest, I, (E-I)*sizeof(T)); + // use memcpy here. Note that I and E are iterators and thus might be + // invalid for memcpy if they are equal. + if (I != E) + memcpy(Dest, I, (E - I) * sizeof(T)); } /// Double the size of the allocated memory, guaranteeing space for at @@ -385,7 +353,7 @@ template class SmallVectorImpl : public SmallVectorTemplateBase::value> { typedef SmallVectorTemplateBase::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 +427,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 +442,10 @@ public: this->setEnd(this->end() + NumInputs); } + void append(std::initializer_list IL) { + append(IL.begin(), IL.end()); + } + void assign(size_type NumElts, const T &Elt) { clear(); if (this->capacity() < NumElts) @@ -484,6 +454,11 @@ public: std::uninitialized_fill(this->begin(), this->end(), Elt); } + void assign(std::initializer_list 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 +652,17 @@ public: return I; } + void insert(iterator I, std::initializer_list IL) { + insert(I, IL.begin(), IL.end()); + } + + 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); + } + SmallVectorImpl &operator=(const SmallVectorImpl &RHS); SmallVectorImpl &operator=(SmallVectorImpl &&RHS); @@ -902,6 +888,10 @@ public: this->append(R.begin(), R.end()); } + SmallVector(std::initializer_list IL) : SmallVectorImpl(N) { + this->assign(IL); + } + SmallVector(const SmallVector &RHS) : SmallVectorImpl(N) { if (!RHS.empty()) SmallVectorImpl::operator=(RHS); @@ -921,6 +911,21 @@ public: SmallVectorImpl::operator=(::std::move(RHS)); return *this; } + + SmallVector(SmallVectorImpl &&RHS) : SmallVectorImpl(N) { + if (!RHS.empty()) + SmallVectorImpl::operator=(::std::move(RHS)); + } + + const SmallVector &operator=(SmallVectorImpl &&RHS) { + SmallVectorImpl::operator=(::std::move(RHS)); + return *this; + } + + const SmallVector &operator=(std::initializer_list IL) { + this->assign(IL); + return *this; + } }; template