Provide image baselines for struct-image-07-t.svg
[chromium-blink-merge.git] / base / ref_counted.h
blobe8413d9b7883e66100823de1b80b9aed9a9a9d34
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef BASE_REF_COUNTED_H_
6 #define BASE_REF_COUNTED_H_
8 #include "base/atomic_ref_count.h"
9 #include "base/thread_collision_warner.h"
11 namespace base {
13 namespace subtle {
15 class RefCountedBase {
16 public:
17 static bool ImplementsThreadSafeReferenceCounting() { return false; }
19 bool HasOneRef() const { return ref_count_ == 1; }
21 protected:
22 RefCountedBase();
23 ~RefCountedBase();
25 void AddRef();
27 // Returns true if the object should self-delete.
28 bool Release();
30 private:
31 int ref_count_;
32 #ifndef NDEBUG
33 bool in_dtor_;
34 #endif
36 DFAKE_MUTEX(add_release_);
38 DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
41 class RefCountedThreadSafeBase {
42 public:
43 static bool ImplementsThreadSafeReferenceCounting() { return true; }
45 bool HasOneRef() const;
47 protected:
48 RefCountedThreadSafeBase();
49 ~RefCountedThreadSafeBase();
51 void AddRef();
53 // Returns true if the object should self-delete.
54 bool Release();
56 private:
57 AtomicRefCount ref_count_;
58 #ifndef NDEBUG
59 bool in_dtor_;
60 #endif
62 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
65 } // namespace subtle
68 // A base class for reference counted classes. Otherwise, known as a cheap
69 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
70 // class from it like so:
72 // class MyFoo : public base::RefCounted<MyFoo> {
73 // ...
74 // private:
75 // friend class base::RefCounted<MyFoo>;
76 // ~MyFoo();
77 // };
79 // You should always make your destructor private, to avoid any code deleting
80 // the object accidently while there are references to it.
81 template <class T>
82 class RefCounted : public subtle::RefCountedBase {
83 public:
84 RefCounted() { }
85 ~RefCounted() { }
87 void AddRef() {
88 subtle::RefCountedBase::AddRef();
91 void Release() {
92 if (subtle::RefCountedBase::Release()) {
93 delete static_cast<T*>(this);
97 private:
98 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
101 // Forward declaration.
102 template <class T, typename Traits> class RefCountedThreadSafe;
104 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
105 // count reaches 0. Overload to delete it on a different thread etc.
106 template<typename T>
107 struct DefaultRefCountedThreadSafeTraits {
108 static void Destruct(T* x) {
109 // Delete through RefCountedThreadSafe to make child classes only need to be
110 // friend with RefCountedThreadSafe instead of this struct, which is an
111 // implementation detail.
112 RefCountedThreadSafe<T, DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
117 // A thread-safe variant of RefCounted<T>
119 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
120 // ...
121 // };
123 // If you're using the default trait, then you should add compile time
124 // asserts that no one else is deleting your object. i.e.
125 // private:
126 // friend class base::RefCountedThreadSafe<MyFoo>;
127 // ~MyFoo();
128 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
129 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
130 public:
131 RefCountedThreadSafe() { }
132 ~RefCountedThreadSafe() { }
134 void AddRef() {
135 subtle::RefCountedThreadSafeBase::AddRef();
138 void Release() {
139 if (subtle::RefCountedThreadSafeBase::Release()) {
140 Traits::Destruct(static_cast<T*>(this));
144 private:
145 friend struct DefaultRefCountedThreadSafeTraits<T>;
146 static void DeleteInternal(T* x) { delete x; }
148 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
152 // A wrapper for some piece of data so we can place other things in
153 // scoped_refptrs<>.
155 template<typename T>
156 class RefCountedData : public base::RefCounted< base::RefCountedData<T> > {
157 public:
158 RefCountedData() : data() {}
159 RefCountedData(const T& in_value) : data(in_value) {}
161 T data;
164 } // namespace base
167 // A smart pointer class for reference counted objects. Use this class instead
168 // of calling AddRef and Release manually on a reference counted object to
169 // avoid common memory leaks caused by forgetting to Release an object
170 // reference. Sample usage:
172 // class MyFoo : public RefCounted<MyFoo> {
173 // ...
174 // };
176 // void some_function() {
177 // scoped_refptr<MyFoo> foo = new MyFoo();
178 // foo->Method(param);
179 // // |foo| is released when this function returns
180 // }
182 // void some_other_function() {
183 // scoped_refptr<MyFoo> foo = new MyFoo();
184 // ...
185 // foo = NULL; // explicitly releases |foo|
186 // ...
187 // if (foo)
188 // foo->Method(param);
189 // }
191 // The above examples show how scoped_refptr<T> acts like a pointer to T.
192 // Given two scoped_refptr<T> classes, it is also possible to exchange
193 // references between the two objects, like so:
195 // {
196 // scoped_refptr<MyFoo> a = new MyFoo();
197 // scoped_refptr<MyFoo> b;
199 // b.swap(a);
200 // // now, |b| references the MyFoo object, and |a| references NULL.
201 // }
203 // To make both |a| and |b| in the above example reference the same MyFoo
204 // object, simply use the assignment operator:
206 // {
207 // scoped_refptr<MyFoo> a = new MyFoo();
208 // scoped_refptr<MyFoo> b;
210 // b = a;
211 // // now, |a| and |b| each own a reference to the same MyFoo object.
212 // }
214 template <class T>
215 class scoped_refptr {
216 public:
217 scoped_refptr() : ptr_(NULL) {
220 scoped_refptr(T* p) : ptr_(p) {
221 if (ptr_)
222 ptr_->AddRef();
225 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
226 if (ptr_)
227 ptr_->AddRef();
230 template <typename U>
231 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
232 if (ptr_)
233 ptr_->AddRef();
236 ~scoped_refptr() {
237 if (ptr_)
238 ptr_->Release();
241 T* get() const { return ptr_; }
242 operator T*() const { return ptr_; }
243 T* operator->() const { return ptr_; }
245 // Release a pointer.
246 // The return value is the current pointer held by this object.
247 // If this object holds a NULL pointer, the return value is NULL.
248 // After this operation, this object will hold a NULL pointer,
249 // and will not own the object any more.
250 T* release() {
251 T* retVal = ptr_;
252 ptr_ = NULL;
253 return retVal;
256 scoped_refptr<T>& operator=(T* p) {
257 // AddRef first so that self assignment should work
258 if (p)
259 p->AddRef();
260 if (ptr_ )
261 ptr_ ->Release();
262 ptr_ = p;
263 return *this;
266 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
267 return *this = r.ptr_;
270 template <typename U>
271 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
272 return *this = r.get();
275 void swap(T** pp) {
276 T* p = ptr_;
277 ptr_ = *pp;
278 *pp = p;
281 void swap(scoped_refptr<T>& r) {
282 swap(&r.ptr_);
285 protected:
286 T* ptr_;
289 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
290 // having to retype all the template arguments
291 template <typename T>
292 scoped_refptr<T> make_scoped_refptr(T* t) {
293 return scoped_refptr<T>(t);
296 #endif // BASE_REF_COUNTED_H_