Add an unwind_to field to basic blocks, making them Users instead of Values.
[oota-llvm.git] / include / llvm / ADT / SmallVector.h
index 9f2842a63890c960b716b2afebc41544f2e8824b..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.
 //
 //===----------------------------------------------------------------------===//
 //
 #ifndef LLVM_ADT_SMALLVECTOR_H
 #define LLVM_ADT_SMALLVECTOR_H
 
+#include "llvm/ADT/iterator"
 #include <algorithm>
-#include <iterator>
 #include <memory>
 
 #ifdef _MSC_VER
 namespace std {
-  // Fix bug in VC++ implementation of std::uninitialized_copy.  Define
-  // additional overloads so that the copy is recognized as a scalar and
-  // not an object copy.
+#if _MSC_VER <= 1310
+  // Work around flawed VC++ implementation of std::uninitialized_copy.  Define
+  // additional overloads so that elements with pointer types are recognized as
+  // scalars and not objects, causing bizarre type conversion errors.
   template<class T1, class T2>
   inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
-         _Scalar_ptr_iterator_tag _Cat;
-         return _Cat;
+    _Scalar_ptr_iterator_tag _Cat;
+    return _Cat;
   }
 
   template<class T1, class T2>
   inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
-         _Scalar_ptr_iterator_tag _Cat;
-         return _Cat;
+    _Scalar_ptr_iterator_tag _Cat;
+    return _Cat;
   }
+#else
+// FIXME: It is not clear if the problem is fixed in VS 2005.  What is clear
+// is that the above hack won't work if it wasn't fixed.
+#endif
 }
 #endif
 
@@ -68,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() {
@@ -77,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];
   }
@@ -142,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;
@@ -154,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;
@@ -184,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);
@@ -276,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
@@ -303,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;
@@ -318,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;
@@ -371,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);
@@ -437,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--)
@@ -450,7 +483,8 @@ public:
   }
   
   SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
-    operator=(RHS);
+    if (!RHS.empty())
+      operator=(RHS);
   }
   
   const SmallVector &operator=(const SmallVector &RHS) {