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