Replace the hashing functions on APInt and APFloat with overloads of the
[oota-llvm.git] / include / llvm / ADT / IntrusiveRefCntPtr.h
index 4709d45b2a59c5007780b20fbeb2e3c7e7abcf6d..3a1a3f4634cfdc4dbe53ce4b439386ed159368b9 100644 (file)
@@ -1,4 +1,4 @@
-//== llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer ----*- C++ -*-==//
+//== llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer ---*- C++ -*-==//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -42,18 +42,17 @@ namespace llvm {
 //===----------------------------------------------------------------------===//
   template <class Derived>
   class RefCountedBase {
-    unsigned ref_cnt;
+    mutable unsigned ref_cnt;
 
-  protected:
+  public:
     RefCountedBase() : ref_cnt(0) {}
+    RefCountedBase(const RefCountedBase &) : ref_cnt(0) {}
 
-    void Retain() { ++ref_cnt; }
-    void Release() {
+    void Retain() const { ++ref_cnt; }
+    void Release() const {
       assert (ref_cnt > 0 && "Reference count is already zero.");
-      if (--ref_cnt == 0) delete static_cast<Derived*>(this);
+      if (--ref_cnt == 0) delete static_cast<const Derived*>(this);
     }
-
-    friend class IntrusiveRefCntPtr<Derived>;
   };
 
 //===----------------------------------------------------------------------===//
@@ -64,23 +63,32 @@ namespace llvm {
 ///  inherit from RefCountedBaseVPTR can't be allocated on stack -
 ///  attempting to do this will produce a compile error.
 //===----------------------------------------------------------------------===//
-  template <class Derived>
   class RefCountedBaseVPTR {
-    unsigned ref_cnt;
+    mutable unsigned ref_cnt;
+    virtual void anchor();
 
   protected:
     RefCountedBaseVPTR() : ref_cnt(0) {}
+    RefCountedBaseVPTR(const RefCountedBaseVPTR &) : ref_cnt(0) {}
+
     virtual ~RefCountedBaseVPTR() {}
 
-    void Retain() { ++ref_cnt; }
-    void Release() {
+    void Retain() const { ++ref_cnt; }
+    void Release() const {
       assert (ref_cnt > 0 && "Reference count is already zero.");
       if (--ref_cnt == 0) delete this;
     }
 
-    friend class IntrusiveRefCntPtr<Derived>;
+    template <typename T>
+    friend struct IntrusiveRefCntPtrInfo;
   };
 
+  
+  template <typename T> struct IntrusiveRefCntPtrInfo {
+    static void retain(T *obj) { obj->Retain(); }
+    static void release(T *obj) { obj->Release(); }
+  };
+  
 //===----------------------------------------------------------------------===//
 /// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
 ///  that assumes the wrapped object has a reference count associated
@@ -107,7 +115,7 @@ namespace llvm {
 
     explicit IntrusiveRefCntPtr() : Obj(0) {}
 
-    explicit IntrusiveRefCntPtr(T* obj) : Obj(obj) {
+    IntrusiveRefCntPtr(T* obj) : Obj(obj) {
       retain();
     }
 
@@ -121,6 +129,11 @@ namespace llvm {
       retain();
     }
 
+    IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr& S) {
+      replace(S.getPtr());
+      return *this;
+    }
+
     template <class X>
     IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr<X>& S) {
       replace(S.getPtr());
@@ -140,7 +153,7 @@ namespace llvm {
 
     T* getPtr() const { return Obj; }
 
-    typedef T * IntrusiveRefCntPtr::*unspecified_bool_type;
+    typedef T* (IntrusiveRefCntPtr::*unspecified_bool_type) () const;
     operator unspecified_bool_type() const {
       return Obj == 0 ? 0 : &IntrusiveRefCntPtr::getPtr;
     }
@@ -151,12 +164,21 @@ namespace llvm {
       Obj = tmp;
     }
 
+    void reset() {
+      release();
+      Obj = 0;
+    }
+
+    void resetWithoutRelease() {
+      Obj = 0;
+    }
+
   private:
-    void retain() { if (Obj) Obj->Retain(); }
-    void release() { if (Obj) Obj->Release(); }
+    void retain() { if (Obj) IntrusiveRefCntPtrInfo<T>::retain(Obj); }
+    void release() { if (Obj) IntrusiveRefCntPtrInfo<T>::release(Obj); }
 
     void replace(T* S) {
-      this_type(S).swap(this);
+      this_type(S).swap(*this);
     }
   };