Fix a silly restriction on the fast-path for hash_combine_range. This
[oota-llvm.git] / include / llvm / ADT / TinyPtrVector.h
index e1dc3df56169b27eabffc3e530bd2309e053ffd3..5014517c9e05bae4a433bb402b165f8edc85e596 100644 (file)
@@ -6,10 +6,6 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-// This file defines the Type class.
-//
-//===----------------------------------------------------------------------===//
 
 #ifndef LLVM_ADT_TINYPTRVECTOR_H
 #define LLVM_ADT_TINYPTRVECTOR_H
@@ -41,9 +37,18 @@ public:
       delete V;
   }
   
-  /// empty() - This vector can be empty if it contains no element, or if it
-  /// contains a pointer to an empty vector.
+  // implicit conversion operator to ArrayRef.
+  operator ArrayRef<EltTy>() const {
+    if (Val.isNull())
+      return ArrayRef<EltTy>();
+    if (Val.template is<EltTy>())
+      return *Val.getAddrOfPtr1();
+    return *Val.template get<VecTy*>();
+  }
+  
   bool empty() const {
+    // This vector can be empty if it contains no element, or if it
+    // contains a pointer to an empty vector.
     if (Val.isNull()) return true;
     if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
       return Vec->empty();
@@ -53,11 +58,42 @@ public:
   unsigned size() const {
     if (empty())
       return 0;
-    if (Val. template is<EltTy>())
+    if (Val.template is<EltTy>())
       return 1;
-    return Val. template get<VecTy*>()->size();
+    return Val.template get<VecTy*>()->size();
   }
   
+  typedef const EltTy *const_iterator;
+  typedef EltTy *iterator;
+
+  iterator begin() {
+    if (empty())
+      return 0;
+    
+    if (Val.template is<EltTy>())
+      return Val.getAddrOfPtr1();
+    
+    return Val.template get<VecTy *>()->begin();
+
+  }
+  iterator end() {
+    if (empty())
+      return 0;
+    
+    if (Val.template is<EltTy>())
+      return begin() + 1;
+    
+    return Val.template get<VecTy *>()->end();
+  }
+
+  const_iterator begin() const {
+    return (const_iterator)const_cast<TinyPtrVector*>(this)->begin();
+  }
+
+  const_iterator end() const {
+    return (const_iterator)const_cast<TinyPtrVector*>(this)->end();
+  }
+
   EltTy operator[](unsigned i) const {
     assert(!Val.isNull() && "can't index into an empty vector");
     if (EltTy V = Val.template dyn_cast<EltTy>()) {
@@ -65,9 +101,9 @@ public:
       return V;
     }
     
-    assert(i < Val. template get<VecTy*>()->size() && 
+    assert(i < Val.template get<VecTy*>()->size() && 
            "tinyvector index out of range");
-    return (*Val. template get<VecTy*>())[i];
+    return (*Val.template get<VecTy*>())[i];
   }
   
   EltTy front() const {
@@ -87,7 +123,7 @@ public:
     }
     
     // If we have a single value, convert to a vector.
-    if (EltTy V = Val.template  dyn_cast<EltTy>()) {
+    if (EltTy V = Val.template dyn_cast<EltTy>()) {
       Val = new VecTy();
       Val.template get<VecTy*>()->push_back(V);
     }
@@ -98,7 +134,7 @@ public:
   
   void clear() {
     // If we have a single value, convert to empty.
-    if (EltTy V = Val.template dyn_cast<EltTy>()) {
+    if (Val.template is<EltTy>()) {
       Val = (EltTy)0;
     } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
       // If we have a vector form, just clear it.
@@ -106,6 +142,20 @@ public:
     }
     // Otherwise, we're already empty.
   }
+
+  iterator erase(iterator I) {
+    // If we have a single value, convert to empty.
+    if (Val.template is<EltTy>()) {
+      if (I == begin())
+        Val = (EltTy)0;
+    } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
+      // multiple items in a vector; just do the erase, there is no
+      // benefit to collapsing back to a pointer
+      return Vec->erase(I);
+    }
+
+    return 0;
+  }
   
 private:
   void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.