X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FIntrusiveRefCntPtr.h;h=a9724ee15447cb9248b819caa8e4bd005c15588a;hb=c312f098999d4640cf91934632ccecfc9ef30b85;hp=37d4ac9d29df518abaa753357cf406257502fde1;hpb=a2769a33c94f021a609a462b28ebea069eba6f74;p=oota-llvm.git diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index 37d4ac9d29d..a9724ee1544 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -21,9 +21,9 @@ #ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR #define LLVM_ADT_INTRUSIVE_REF_CNT_PTR -#include - #include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" +#include namespace llvm { @@ -34,7 +34,7 @@ namespace llvm { /// RefCountedBase - A generic base class for objects that wish to /// have their lifetimes managed using reference counts. Classes /// subclass RefCountedBase to obtain such functionality, and are -/// typically handled with IntrusivePtr "smart pointers" (see below) +/// typically handled with IntrusiveRefCntPtr "smart pointers" (see below) /// which automatically handle the management of reference counts. /// Objects that subclass RefCountedBase should not be allocated on /// the stack, as invoking "delete" (which is called when the @@ -42,18 +42,17 @@ namespace llvm { //===----------------------------------------------------------------------===// template 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(this); + if (--ref_cnt == 0) delete static_cast(this); } - - friend class IntrusiveRefCntPtr; }; //===----------------------------------------------------------------------===// @@ -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 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; + template + friend struct IntrusiveRefCntPtrInfo; }; + + template 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(); } @@ -115,25 +123,25 @@ namespace llvm { retain(); } - template - IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) - : Obj(S.getPtr()) { - retain(); +#if LLVM_USE_RVALUE_REFERENCES + IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) { + S.Obj = 0; } - IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr& S) { - replace(S.getPtr()); - return *this; + template + IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.getPtr()) { + S.Obj = 0; } +#endif template - IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr& S) { - replace(S.getPtr()); - return *this; + IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) + : Obj(S.getPtr()) { + retain(); } - IntrusiveRefCntPtr& operator=(T * S) { - replace(S); + IntrusiveRefCntPtr& operator=(IntrusiveRefCntPtr S) { + swap(S); return *this; } @@ -156,13 +164,18 @@ namespace llvm { Obj = tmp; } - private: - void retain() { if (Obj) Obj->Retain(); } - void release() { if (Obj) Obj->Release(); } + void reset() { + release(); + Obj = 0; + } - void replace(T* S) { - this_type(S).swap(*this); + void resetWithoutRelease() { + Obj = 0; } + + private: + void retain() { if (Obj) IntrusiveRefCntPtrInfo::retain(Obj); } + void release() { if (Obj) IntrusiveRefCntPtrInfo::release(Obj); } }; template