implement operator= for smallptrset
authorChris Lattner <sabre@nondot.org>
Mon, 9 Jul 2007 16:54:03 +0000 (16:54 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 9 Jul 2007 16:54:03 +0000 (16:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@38460 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/SmallPtrSet.h
lib/Support/SmallPtrSet.cpp

index 40e9bb4139c8d8a19142399e7b30cdb4d0e5c48a..80c078f35bd197494f6d65be0590d85f030cc89a 100644 (file)
@@ -127,6 +127,10 @@ private:
   
   /// Grow - Allocate a larger backing store for the buckets and move it over.
   void Grow();
+  
+  void operator=(const SmallPtrSetImpl &RHS);  // DO NOT IMPLEMENT.
+protected:
+  void CopyFrom(const SmallPtrSetImpl &RHS);
 };
 
 /// SmallPtrSetIteratorImpl - This is the common base class shared between all
@@ -233,6 +237,16 @@ public:
   inline iterator end() const {
     return iterator(CurArray+CurArraySize);
   }
+  
+  // Allow assignment from any smallptrset with the same element type even if it
+  // doesn't have the same smallsize.
+  template<unsigned RHSSize>
+  const SmallPtrSet<PtrType, SmallSize>
+  operator=(const SmallPtrSet<PtrType, RHSSize> &RHS) {
+    CopyFrom(RHS);
+    return *this;
+  }
+
 };
 
 }
index da1a11029e79dea9f828bc5eb05ff2c9d8fa0565..81c4bc752fb2d9ecad48a08a2db11bf6b0f3e063 100644 (file)
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/MathExtras.h"
 using namespace llvm;
 
 bool SmallPtrSetImpl::insert(void *Ptr) {
@@ -172,3 +173,38 @@ SmallPtrSetImpl::SmallPtrSetImpl(const SmallPtrSetImpl& that) {
     }
   }
 }
+
+/// CopyFrom - implement operator= from a smallptrset that has the same pointer
+/// type, but may have a different small size.
+void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) {
+  // Allocate space if needed or clear the current elements out of the array.
+  if (CurArraySize < RHS.size()*2) {
+    if (!isSmall())
+      delete [] CurArray;
+    
+    // Get a power of two larger than twice the RHS size.
+    CurArraySize = 1 << Log2_32(RHS.size()*4);
+    
+    // Install the new array.  Clear all the buckets to empty.
+    CurArray = new void*[CurArraySize+1];
+    memset(CurArray, -1, CurArraySize*sizeof(void*));
+    
+    // The end pointer, always valid, is set to a valid element to help the
+    // iterator.
+    CurArray[CurArraySize] = 0;
+    
+  } else if (!empty()) {
+    clear();
+  }
+  
+  // Now that we know we have enough space, and that the current array is empty,
+  // copy over all the elements from the RHS.
+  
+  for (void **BucketPtr = RHS.CurArray, **E = RHS.CurArray+RHS.CurArraySize;
+       BucketPtr != E; ++BucketPtr) {
+    // Copy over the element if it is valid.
+    void *Elt = *BucketPtr;
+    if (Elt != getTombstoneMarker() && Elt != getEmptyMarker())
+      *const_cast<void**>(FindBucketFor(Elt)) = Elt;
+  }
+}