summaryrefslogtreecommitdiff
path: root/include/llvm/ADT/SmallVector.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ADT/SmallVector.h')
-rw-r--r--include/llvm/ADT/SmallVector.h98
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>