• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 under third_party_mods/chromium or at:
4 // http://src.chromium.org/svn/trunk/src/LICENSE
5 
6 #ifndef SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
7 #define SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
8 
9 namespace webrtc {
10 
11 // Extracted from Chromium's src/base/memory/ref_counted.h.
12 
13 //
14 // A smart pointer class for reference counted objects.  Use this class instead
15 // of calling AddRef and Release manually on a reference counted object to
16 // avoid common memory leaks caused by forgetting to Release an object
17 // reference.  Sample usage:
18 //
19 //   class MyFoo : public RefCounted<MyFoo> {
20 //    ...
21 //   };
22 //
23 //   void some_function() {
24 //     scoped_refptr<MyFoo> foo = new MyFoo();
25 //     foo->Method(param);
26 //     // |foo| is released when this function returns
27 //   }
28 //
29 //   void some_other_function() {
30 //     scoped_refptr<MyFoo> foo = new MyFoo();
31 //     ...
32 //     foo = NULL;  // explicitly releases |foo|
33 //     ...
34 //     if (foo)
35 //       foo->Method(param);
36 //   }
37 //
38 // The above examples show how scoped_refptr<T> acts like a pointer to T.
39 // Given two scoped_refptr<T> classes, it is also possible to exchange
40 // references between the two objects, like so:
41 //
42 //   {
43 //     scoped_refptr<MyFoo> a = new MyFoo();
44 //     scoped_refptr<MyFoo> b;
45 //
46 //     b.swap(a);
47 //     // now, |b| references the MyFoo object, and |a| references NULL.
48 //   }
49 //
50 // To make both |a| and |b| in the above example reference the same MyFoo
51 // object, simply use the assignment operator:
52 //
53 //   {
54 //     scoped_refptr<MyFoo> a = new MyFoo();
55 //     scoped_refptr<MyFoo> b;
56 //
57 //     b = a;
58 //     // now, |a| and |b| each own a reference to the same MyFoo object.
59 //   }
60 //
61 template <class T>
62 class scoped_refptr {
63  public:
scoped_refptr()64   scoped_refptr() : ptr_(NULL) {
65   }
66 
scoped_refptr(T * p)67   scoped_refptr(T* p) : ptr_(p) {
68     if (ptr_)
69       ptr_->AddRef();
70   }
71 
scoped_refptr(const scoped_refptr<T> & r)72   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
73     if (ptr_)
74       ptr_->AddRef();
75   }
76 
77   template <typename U>
scoped_refptr(const scoped_refptr<U> & r)78   scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
79     if (ptr_)
80       ptr_->AddRef();
81   }
82 
~scoped_refptr()83   ~scoped_refptr() {
84     if (ptr_)
85       ptr_->Release();
86   }
87 
get()88   T* get() const { return ptr_; }
89   operator T*() const { return ptr_; }
90   T* operator->() const { return ptr_; }
91 
92   // Release a pointer.
93   // The return value is the current pointer held by this object.
94   // If this object holds a NULL pointer, the return value is NULL.
95   // After this operation, this object will hold a NULL pointer,
96   // and will not own the object any more.
release()97   T* release() {
98     T* retVal = ptr_;
99     ptr_ = NULL;
100     return retVal;
101   }
102 
103   scoped_refptr<T>& operator=(T* p) {
104     // AddRef first so that self assignment should work
105     if (p)
106       p->AddRef();
107     if (ptr_ )
108       ptr_->Release();
109     ptr_ = p;
110     return *this;
111   }
112 
113   scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
114     return *this = r.ptr_;
115   }
116 
117   template <typename U>
118   scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
119     return *this = r.get();
120   }
121 
swap(T ** pp)122   void swap(T** pp) {
123     T* p = ptr_;
124     ptr_ = *pp;
125     *pp = p;
126   }
127 
swap(scoped_refptr<T> & r)128   void swap(scoped_refptr<T>& r) {
129     swap(&r.ptr_);
130   }
131 
132  protected:
133   T* ptr_;
134 };
135 }  // namespace webrtc
136 
137 #endif  // SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
138