Add an unwind_to field to basic blocks, making them Users instead of Values.
[oota-llvm.git] / include / llvm / ADT / SmallVector.h
index dc37ac744991fd26fb3bade1b59b1ad5ad99a22c..a6b65dd58b410ae70bf4f01a68c70efac0a98bea 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -14,8 +14,8 @@
 #ifndef LLVM_ADT_SMALLVECTOR_H
 #define LLVM_ADT_SMALLVECTOR_H
 
+#include "llvm/ADT/iterator"
 #include <algorithm>
-#include <iterator>
 #include <memory>
 
 #ifdef _MSC_VER
@@ -73,7 +73,9 @@ protected:
 public:
   // Default ctor - Initialize to empty.
   SmallVectorImpl(unsigned N)
-    : Begin((T*)&FirstEl), End((T*)&FirstEl), Capacity((T*)&FirstEl+N) {
+    : Begin(reinterpret_cast<T*>(&FirstEl)), 
+      End(reinterpret_cast<T*>(&FirstEl)), 
+      Capacity(reinterpret_cast<T*>(&FirstEl)+N) {
   }
   
   ~SmallVectorImpl() {
@@ -82,24 +84,35 @@ public:
 
     // If this wasn't grown from the inline copy, deallocate the old space.
     if (!isSmall())
-      delete[] (char*)Begin;
+      delete[] reinterpret_cast<char*>(Begin);
   }
   
   typedef size_t size_type;
   typedef T* iterator;
   typedef const T* const_iterator;
+  
+  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
+  typedef std::reverse_iterator<iterator>  reverse_iterator;
+  
   typedef T& reference;
   typedef const T& const_reference;
 
   bool empty() const { return Begin == End; }
   size_type size() const { return End-Begin; }
-  
+
+  // forward iterator creation methods.
   iterator begin() { return Begin; }
   const_iterator begin() const { return Begin; }
-
   iterator end() { return End; }
   const_iterator end() const { return End; }
   
+  // reverse iterator creation methods.
+  reverse_iterator rbegin()            { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+  reverse_iterator rend()              { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+  
+  
   reference operator[](unsigned idx) {
     return Begin[idx];
   }
@@ -147,7 +160,7 @@ public:
       destroy_range(Begin+N, End);
       End = Begin+N;
     } else if (N > size()) {
-      if (Begin+N > Capacity)
+      if (unsigned(Capacity-Begin) < N)
         grow(N);
       construct_range(End, Begin+N, T());
       End = Begin+N;
@@ -159,7 +172,7 @@ public:
       destroy_range(Begin+N, End);
       End = Begin+N;
     } else if (N > size()) {
-      if (Begin+N > Capacity)
+      if (unsigned(Capacity-Begin) < N)
         grow(N);
       construct_range(End, Begin+N, NV);
       End = Begin+N;
@@ -189,7 +202,7 @@ public:
   
   void assign(unsigned NumElts, const T &Elt) {
     clear();
-    if (Begin+NumElts > Capacity)
+    if (unsigned(Capacity-Begin) < NumElts)
       grow(NumElts);
     End = Begin+NumElts;
     construct_range(Begin, End, Elt);
@@ -281,11 +294,22 @@ public:
   
   const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
   
+  bool operator==(const SmallVectorImpl &RHS) const {
+    if (size() != RHS.size()) return false;
+    for (T *This = Begin, *That = RHS.Begin, *End = Begin+size(); 
+         This != End; ++This, ++That)
+      if (*This != *That)
+        return false;
+    return true;
+  }
+  bool operator!=(const SmallVectorImpl &RHS) const { return !(*this == RHS); }
+  
 private:
   /// isSmall - Return true if this is a smallvector which has not had dynamic
   /// memory allocated for it.
   bool isSmall() const {
-    return (void*)Begin == (void*)&FirstEl;
+    return reinterpret_cast<const void*>(Begin) == 
+           reinterpret_cast<const void*>(&FirstEl);
   }
 
   /// grow - double the size of the allocated memory, guaranteeing space for at
@@ -308,8 +332,8 @@ private:
 // Define this out-of-line to dissuade the C++ compiler from inlining it.
 template <typename T>
 void SmallVectorImpl<T>::grow(unsigned MinSize) {
-  unsigned CurCapacity = Capacity-Begin;
-  unsigned CurSize = size();
+  unsigned CurCapacity = unsigned(Capacity-Begin);
+  unsigned CurSize = unsigned(size());
   unsigned NewCapacity = 2*CurCapacity;
   if (NewCapacity < MinSize)
     NewCapacity = MinSize;
@@ -323,7 +347,7 @@ void SmallVectorImpl<T>::grow(unsigned MinSize) {
   
   // If this wasn't grown from the inline copy, deallocate the old space.
   if (!isSmall())
-    delete[] (char*)Begin;
+    delete[] reinterpret_cast<char*>(Begin);
   
   Begin = NewElts;
   End = NewElts+CurSize;
@@ -376,11 +400,15 @@ SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
   
   // If we already have sufficient space, assign the common elements, then
   // destroy any excess.
-  unsigned RHSSize = RHS.size();
-  unsigned CurSize = size();
+  unsigned RHSSize = unsigned(RHS.size());
+  unsigned CurSize = unsigned(size());
   if (CurSize >= RHSSize) {
     // Assign common elements.
-    iterator NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
+    iterator NewEnd;
+    if (RHSSize)
+      NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
+    else
+      NewEnd = Begin;
     
     // Destroy excess elements.
     destroy_range(NewEnd, End);
@@ -442,7 +470,7 @@ public:
   SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
   }
   
-  SmallVector(unsigned Size, const T &Value)
+  explicit SmallVector(unsigned Size, const T &Value = T())
     : SmallVectorImpl<T>(NumTsAvailable) {
     this->reserve(Size);
     while (Size--)
@@ -455,7 +483,8 @@ public:
   }
   
   SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
-    operator=(RHS);
+    if (!RHS.empty())
+      operator=(RHS);
   }
   
   const SmallVector &operator=(const SmallVector &RHS) {