Revert of https://codereview.chromium.org/88993002/
[chromium-blink-merge.git] / base / memory / ref_counted.h
blobaae36b17c2f19a5a8d845e5e7d0daf0fdcbf93e7
1 // Copyright (c) 2012 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_MEMORY_REF_COUNTED_H_
6 #define BASE_MEMORY_REF_COUNTED_H_
8 #include <cassert>
10 #include "base/atomic_ref_count.h"
11 #include "base/base_export.h"
12 #include "base/compiler_specific.h"
13 #include "base/threading/thread_collision_warner.h"
15 namespace base {
17 namespace subtle {
19 class BASE_EXPORT RefCountedBase {
20 public:
21 bool HasOneRef() const { return ref_count_ == 1; }
23 protected:
24 RefCountedBase();
25 ~RefCountedBase();
27 void AddRef() const;
29 // Returns true if the object should self-delete.
30 bool Release() const;
32 private:
33 mutable int ref_count_;
34 #ifndef NDEBUG
35 mutable bool in_dtor_;
36 #endif
38 DFAKE_MUTEX(add_release_);
40 DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
43 class BASE_EXPORT RefCountedThreadSafeBase {
44 public:
45 bool HasOneRef() const;
47 protected:
48 RefCountedThreadSafeBase();
49 ~RefCountedThreadSafeBase();
51 void AddRef() const;
53 // Returns true if the object should self-delete.
54 bool Release() const;
56 private:
57 mutable AtomicRefCount ref_count_;
58 #ifndef NDEBUG
59 mutable 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() {}
86 void AddRef() const {
87 subtle::RefCountedBase::AddRef();
90 void Release() const {
91 if (subtle::RefCountedBase::Release()) {
92 delete static_cast<const T*>(this);
96 protected:
97 ~RefCounted() {}
99 private:
100 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
103 // Forward declaration.
104 template <class T, typename Traits> class RefCountedThreadSafe;
106 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
107 // count reaches 0. Overload to delete it on a different thread etc.
108 template<typename T>
109 struct DefaultRefCountedThreadSafeTraits {
110 static void Destruct(const T* x) {
111 // Delete through RefCountedThreadSafe to make child classes only need to be
112 // friend with RefCountedThreadSafe instead of this struct, which is an
113 // implementation detail.
114 RefCountedThreadSafe<T,
115 DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
120 // A thread-safe variant of RefCounted<T>
122 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
123 // ...
124 // };
126 // If you're using the default trait, then you should add compile time
127 // asserts that no one else is deleting your object. i.e.
128 // private:
129 // friend class base::RefCountedThreadSafe<MyFoo>;
130 // ~MyFoo();
131 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
132 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
133 public:
134 RefCountedThreadSafe() {}
136 void AddRef() const {
137 subtle::RefCountedThreadSafeBase::AddRef();
140 void Release() const {
141 if (subtle::RefCountedThreadSafeBase::Release()) {
142 Traits::Destruct(static_cast<const T*>(this));
146 protected:
147 ~RefCountedThreadSafe() {}
149 private:
150 friend struct DefaultRefCountedThreadSafeTraits<T>;
151 static void DeleteInternal(const T* x) { delete x; }
153 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
157 // A thread-safe wrapper for some piece of data so we can place other
158 // things in scoped_refptrs<>.
160 template<typename T>
161 class RefCountedData
162 : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
163 public:
164 RefCountedData() : data() {}
165 RefCountedData(const T& in_value) : data(in_value) {}
167 T data;
169 private:
170 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
171 ~RefCountedData() {}
174 } // namespace base
177 // A smart pointer class for reference counted objects. Use this class instead
178 // of calling AddRef and Release manually on a reference counted object to
179 // avoid common memory leaks caused by forgetting to Release an object
180 // reference. Sample usage:
182 // class MyFoo : public RefCounted<MyFoo> {
183 // ...
184 // };
186 // void some_function() {
187 // scoped_refptr<MyFoo> foo = new MyFoo();
188 // foo->Method(param);
189 // // |foo| is released when this function returns
190 // }
192 // void some_other_function() {
193 // scoped_refptr<MyFoo> foo = new MyFoo();
194 // ...
195 // foo = NULL; // explicitly releases |foo|
196 // ...
197 // if (foo)
198 // foo->Method(param);
199 // }
201 // The above examples show how scoped_refptr<T> acts like a pointer to T.
202 // Given two scoped_refptr<T> classes, it is also possible to exchange
203 // references between the two objects, like so:
205 // {
206 // scoped_refptr<MyFoo> a = new MyFoo();
207 // scoped_refptr<MyFoo> b;
209 // b.swap(a);
210 // // now, |b| references the MyFoo object, and |a| references NULL.
211 // }
213 // To make both |a| and |b| in the above example reference the same MyFoo
214 // object, simply use the assignment operator:
216 // {
217 // scoped_refptr<MyFoo> a = new MyFoo();
218 // scoped_refptr<MyFoo> b;
220 // b = a;
221 // // now, |a| and |b| each own a reference to the same MyFoo object.
222 // }
224 template <class T>
225 class scoped_refptr {
226 public:
227 typedef T element_type;
229 scoped_refptr() : ptr_(NULL) {
232 scoped_refptr(T* p) : ptr_(p) {
233 if (ptr_)
234 ptr_->AddRef();
237 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
238 if (ptr_)
239 ptr_->AddRef();
242 template <typename U>
243 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
244 if (ptr_)
245 ptr_->AddRef();
248 ~scoped_refptr() {
249 if (ptr_)
250 ptr_->Release();
253 T* get() const { return ptr_; }
255 // Allow scoped_refptr<C> to be used in boolean expression
256 // and comparison operations.
257 operator T*() const { return ptr_; }
259 T* operator->() const {
260 assert(ptr_ != NULL);
261 return ptr_;
264 scoped_refptr<T>& operator=(T* p) {
265 // AddRef first so that self assignment should work
266 if (p)
267 p->AddRef();
268 T* old_ptr = ptr_;
269 ptr_ = p;
270 if (old_ptr)
271 old_ptr->Release();
272 return *this;
275 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
276 return *this = r.ptr_;
279 template <typename U>
280 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
281 return *this = r.get();
284 void swap(T** pp) {
285 T* p = ptr_;
286 ptr_ = *pp;
287 *pp = p;
290 void swap(scoped_refptr<T>& r) {
291 swap(&r.ptr_);
294 protected:
295 T* ptr_;
298 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
299 // having to retype all the template arguments
300 template <typename T>
301 scoped_refptr<T> make_scoped_refptr(T* t) {
302 return scoped_refptr<T>(t);
305 #endif // BASE_MEMORY_REF_COUNTED_H_