llvm.org GIT mirror llvm / 95e7834
Update per review. Patch by Mikhail Glushenkov! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47628 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 12 years ago
1 changed file(s) with 19 addition(s) and 58 deletion(s). Raw diff Collapse all Expand all
2121 #define LLVM_ADT_INTRUSIVE_REF_CNT_PTR
2222
2323 #include
24 #include
2524
2625 #include "llvm/Support/Casting.h"
2726
28 // Forward declarations
29
3027 namespace llvm {
28
3129 template
32 class RefCountedBase;
33
34 template
35 class RefCountedBaseVPTR;
36 }
37
38 template
39 void IntrusivePtrAddRef(llvm::RefCountedBase*);
40
41 template
42 void IntrusivePtrRelease(llvm::RefCountedBase*);
43
44 template
45 void IntrusivePtrAddRef(llvm::RefCountedBaseVPTR*);
46
47 template
48 void IntrusivePtrRelease(llvm::RefCountedBaseVPTR*);
49
50
51 namespace llvm {
30 class IntrusiveRefCntPtr;
5231
5332 //===----------------------------------------------------------------------===//
5433 /// RefCountedBase - A generic base class for objects that wish to
7352 if (--ref_cnt == 0) delete static_cast(this);
7453 }
7554
76 friend void IntrusivePtrAddRef(RefCountedBase*);
77 friend void IntrusivePtrRelease(RefCountedBase*);
55 friend class IntrusiveRefCntPtr;
7856 };
7957
8058 //===----------------------------------------------------------------------===//
8159 /// RefCountedBaseVPTR - A class that has the same function as
8260 /// RefCountedBase, but with a virtual destructor. Should be used
83 /// instead of RefCountedBase for classes that have virtual
84 /// destructors. Classes that inherit from RefCountedBaseVPTR can't
85 /// be allocated on stack.
61 /// instead of RefCountedBase for classes that already have virtual
62 /// methods to enforce dynamic allocation via 'new'. Classes that
63 /// inherit from RefCountedBaseVPTR can't be allocated on stack -
64 /// attempting to do this will produce a compile error.
8665 //===----------------------------------------------------------------------===//
8766 template
8867 class RefCountedBaseVPTR {
9877 if (--ref_cnt == 0) delete this;
9978 }
10079
101 friend void IntrusivePtrAddRef(RefCountedBaseVPTR*);
102 friend void IntrusivePtrRelease(RefCountedBaseVPTR*);
103 };
104
105 }
106
107 //===----------------------------------------------------------------------===//
108 /// IntrusivePtrAddRef - A utility function used by IntrusiveRefCntPtr
109 /// to increment the reference count of an RefCountedBase-derived object.
110 //===----------------------------------------------------------------------===//
111 template
112 void IntrusivePtrAddRef(llvm::RefCountedBase* O) {
113 O->Retain();
114 }
115
116 //===----------------------------------------------------------------------===//
117 /// IntrusivePtrRelease - The complement of IntrusivePtrAddRef;
118 /// decrements the reference count of a RefCounted object.
119 //===----------------------------------------------------------------------===//
120 template
121 void IntrusivePtrRelease(llvm::RefCountedBase* O) {
122 O->Release();
123 }
124
125
126 namespace llvm {
80 friend class IntrusiveRefCntPtr;
81 };
12782
12883 //===----------------------------------------------------------------------===//
12984 /// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
13590 /// incremented and upon destruction of the smart pointer the
13691 /// reference count is decremented. This class also safely handles
13792 /// wrapping NULL pointers.
93 ///
94 /// Reference counting is implemented via calls to
95 /// Obj->Retain()/Obj->Release(). Release() is required to destroy
96 /// the object when the reference count reaches zero. Inheriting from
97 /// RefCountedBase/RefCountedBaseVPTR takes care of this
98 /// automatically.
13899 //===----------------------------------------------------------------------===//
139100 template
140101 class IntrusiveRefCntPtr {
143104 public:
144105 typedef T element_type;
145106
146 explicit IntrusiveRefCntPtr() : Obj(NULL) {}
107 explicit IntrusiveRefCntPtr() : Obj(0) {}
147108
148109 explicit IntrusiveRefCntPtr(T* obj) : Obj(obj) {
149110 retain();
180141
181142 typedef T * IntrusiveRefCntPtr::*unspecified_bool_type;
182143 operator unspecified_bool_type() const {
183 return Obj == NULL ? NULL : &IntrusiveRefCntPtr::getPtr;
144 return Obj == 0 ? 0 : &IntrusiveRefCntPtr::getPtr;
184145 }
185146
186147 void swap(IntrusiveRefCntPtr& other) {
190151 }
191152
192153 private:
193 void retain() { if (Obj) IntrusivePtrAddRef(Obj); }
194 void release() { if (Obj) IntrusivePtrRelease(Obj); }
154 void retain() { if (Obj) Obj->Retain(); }
155 void release() { if (Obj) Obj->Release(); }
195156
196157 void replace(T* S) {
197158 this_type(S).swap(this);