ADT: introduce isWindowsItaniumEnvironment
[oota-llvm.git] / include / llvm / ADT / SmallVector.h
index 0dc8904eaa38b9ba57ba2193a848e94b6a91e925..dcf0354860fa492ec56eb88d1015e5d82058c484 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_ADT_SMALLVECTOR_H
 #define LLVM_ADT_SMALLVECTOR_H
 
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/AlignOf.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MathExtras.h"
@@ -53,7 +54,7 @@ public:
     return size_t((char*)CapacityX - (char*)BeginX);
   }
 
-  bool empty() const { return BeginX == EndX; }
+  bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return BeginX == EndX; }
 };
 
 template <typename T, unsigned N> struct SmallVectorStorage;
@@ -183,13 +184,9 @@ protected:
   /// std::move, but not all stdlibs actually provide that.
   template<typename It1, typename It2>
   static It2 move(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
     for (; I != E; ++I, ++Dest)
       *Dest = ::std::move(*I);
     return Dest;
-#else
-    return ::std::copy(I, E, Dest);
-#endif
   }
 
   /// move_backward - Use move-assignment to move the range
@@ -198,25 +195,17 @@ protected:
   /// std::move_backward, but not all stdlibs actually provide that.
   template<typename It1, typename It2>
   static It2 move_backward(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
     while (I != E)
       *--Dest = ::std::move(*--E);
     return Dest;
-#else
-    return ::std::copy_backward(I, E, Dest);
-#endif
   }
 
   /// uninitialized_move - Move the range [I, E) into the uninitialized
   /// memory starting with "Dest", constructing elements as needed.
   template<typename It1, typename It2>
   static void uninitialized_move(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
     for (; I != E; ++I, ++Dest)
       ::new ((void*) &*Dest) T(::std::move(*I));
-#else
-    ::std::uninitialized_copy(I, E, Dest);
-#endif
   }
 
   /// uninitialized_copy - Copy the range [I, E) onto the uninitialized
@@ -231,32 +220,22 @@ protected:
   /// Guarantees space for at least one more element, or MinSize more
   /// elements if specified.
   void grow(size_t MinSize = 0);
-  
+
 public:
   void push_back(const T &Elt) {
-    if (this->EndX < this->CapacityX) {
-    Retry:
-      ::new ((void*) this->end()) T(Elt);
-      this->setEnd(this->end()+1);
-      return;
-    }
-    this->grow();
-    goto Retry;
+    if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+      this->grow();
+    ::new ((void*) this->end()) T(Elt);
+    this->setEnd(this->end()+1);
   }
 
-#if LLVM_HAS_RVALUE_REFERENCES
   void push_back(T &&Elt) {
-    if (this->EndX < this->CapacityX) {
-    Retry:
-      ::new ((void*) this->end()) T(::std::move(Elt));
-      this->setEnd(this->end()+1);
-      return;
-    }
-    this->grow();
-    goto Retry;
+    if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+      this->grow();
+    ::new ((void*) this->end()) T(::std::move(Elt));
+    this->setEnd(this->end()+1);
   }
-#endif
-  
+
   void pop_back() {
     this->setEnd(this->end()-1);
     this->end()->~T();
@@ -268,7 +247,7 @@ template <typename T, bool isPodLike>
 void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
   size_t CurCapacity = this->capacity();
   size_t CurSize = this->size();
-  // Always grow, even from zero.  
+  // Always grow, even from zero.
   size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
   if (NewCapacity < MinSize)
     NewCapacity = MinSize;
@@ -348,16 +327,12 @@ protected:
   }
 public:
   void push_back(const T &Elt) {
-    if (this->EndX < this->CapacityX) {
-    Retry:
-      memcpy(this->end(), &Elt, sizeof(T));
-      this->setEnd(this->end()+1);
-      return;
-    }
-    this->grow();
-    goto Retry;
+    if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+      this->grow();
+    memcpy(this->end(), &Elt, sizeof(T));
+    this->setEnd(this->end()+1);
   }
-  
+
   void pop_back() {
     this->setEnd(this->end()-1);
   }
@@ -428,11 +403,7 @@ public:
   }
 
   T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() {
-#if LLVM_HAS_RVALUE_REFERENCES
     T Result = ::std::move(this->back());
-#else
-    T Result = this->back();
-#endif
     this->pop_back();
     return Result;
   }
@@ -501,7 +472,6 @@ public:
     return(N);
   }
 
-#if LLVM_HAS_RVALUE_REFERENCES
   iterator insert(iterator I, T &&Elt) {
     if (I == this->end()) {  // Important special case for empty vector.
       this->push_back(::std::move(Elt));
@@ -511,28 +481,26 @@ public:
     assert(I >= this->begin() && "Insertion iterator is out of bounds.");
     assert(I <= this->end() && "Inserting past the end of the vector.");
 
-    if (this->EndX < this->CapacityX) {
-    Retry:
-      ::new ((void*) this->end()) T(::std::move(this->back()));
-      this->setEnd(this->end()+1);
-      // Push everything else over.
-      this->move_backward(I, this->end()-1, this->end());
+    if (this->EndX >= this->CapacityX) {
+      size_t EltNo = I-this->begin();
+      this->grow();
+      I = this->begin()+EltNo;
+    }
 
-      // If we just moved the element we're inserting, be sure to update
-      // the reference.
-      T *EltPtr = &Elt;
-      if (I <= EltPtr && EltPtr < this->EndX)
-        ++EltPtr;
+    ::new ((void*) this->end()) T(::std::move(this->back()));
+    this->setEnd(this->end()+1);
+    // Push everything else over.
+    this->move_backward(I, this->end()-1, this->end());
 
-      *I = ::std::move(*EltPtr);
-      return I;
-    }
-    size_t EltNo = I-this->begin();
-    this->grow();
-    I = this->begin()+EltNo;
-    goto Retry;
+    // If we just moved the element we're inserting, be sure to update
+    // the reference.
+    T *EltPtr = &Elt;
+    if (I <= EltPtr && EltPtr < this->EndX)
+      ++EltPtr;
+
+    *I = ::std::move(*EltPtr);
+    return I;
   }
-#endif
 
   iterator insert(iterator I, const T &Elt) {
     if (I == this->end()) {  // Important special case for empty vector.
@@ -543,26 +511,24 @@ public:
     assert(I >= this->begin() && "Insertion iterator is out of bounds.");
     assert(I <= this->end() && "Inserting past the end of the vector.");
 
-    if (this->EndX < this->CapacityX) {
-    Retry:
-      ::new ((void*) this->end()) T(this->back());
-      this->setEnd(this->end()+1);
-      // Push everything else over.
-      this->move_backward(I, this->end()-1, this->end());
-
-      // If we just moved the element we're inserting, be sure to update
-      // the reference.
-      const T *EltPtr = &Elt;
-      if (I <= EltPtr && EltPtr < this->EndX)
-        ++EltPtr;
-
-      *I = *EltPtr;
-      return I;
+    if (this->EndX >= this->CapacityX) {
+      size_t EltNo = I-this->begin();
+      this->grow();
+      I = this->begin()+EltNo;
     }
-    size_t EltNo = I-this->begin();
-    this->grow();
-    I = this->begin()+EltNo;
-    goto Retry;
+    ::new ((void*) this->end()) T(this->back());
+    this->setEnd(this->end()+1);
+    // Push everything else over.
+    this->move_backward(I, this->end()-1, this->end());
+
+    // If we just moved the element we're inserting, be sure to update
+    // the reference.
+    const T *EltPtr = &Elt;
+    if (I <= EltPtr && EltPtr < this->EndX)
+      ++EltPtr;
+
+    *I = *EltPtr;
+    return I;
   }
 
   iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
@@ -673,9 +639,7 @@ public:
 
   SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
 
-#if LLVM_HAS_RVALUE_REFERENCES
   SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
-#endif
 
   bool operator==(const SmallVectorImpl &RHS) const {
     if (this->size() != RHS.size()) return false;
@@ -793,7 +757,6 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
   return *this;
 }
 
-#if LLVM_HAS_RVALUE_REFERENCES
 template <typename T>
 SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
   // Avoid self-assignment.
@@ -842,7 +805,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
     this->grow(RHSSize);
   } else if (CurSize) {
     // Otherwise, use assignment for the already-constructed elements.
-    this->move(RHS.begin(), RHS.end(), this->begin());
+    this->move(RHS.begin(), RHS.begin()+CurSize, this->begin());
   }
 
   // Move-construct the new elements in place.
@@ -855,7 +818,6 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
   RHS.clear();
   return *this;
 }
-#endif
 
 /// Storage for the SmallVector elements which aren't contained in
 /// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
@@ -894,6 +856,12 @@ public:
     this->append(S, E);
   }
 
+  template <typename RangeTy>
+  explicit SmallVector(const llvm::iterator_range<RangeTy> R)
+      : SmallVectorImpl<T>(N) {
+    this->append(R.begin(), R.end());
+  }
+
   SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
     if (!RHS.empty())
       SmallVectorImpl<T>::operator=(RHS);
@@ -904,7 +872,6 @@ public:
     return *this;
   }
 
-#if LLVM_HAS_RVALUE_REFERENCES
   SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
     if (!RHS.empty())
       SmallVectorImpl<T>::operator=(::std::move(RHS));
@@ -914,8 +881,6 @@ public:
     SmallVectorImpl<T>::operator=(::std::move(RHS));
     return *this;
   }
-#endif
-
 };
 
 template<typename T, unsigned N>