Line data Source code
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 <memory>
67 :
68 : namespace rtc {
69 :
70 : template <class T>
71 : class scoped_refptr {
72 : public:
73 0 : scoped_refptr() : ptr_(NULL) {
74 0 : }
75 :
76 0 : scoped_refptr(T* p) : ptr_(p) {
77 0 : if (ptr_)
78 0 : ptr_->AddRef();
79 0 : }
80 :
81 0 : scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
82 0 : if (ptr_)
83 0 : ptr_->AddRef();
84 0 : }
85 :
86 : template <typename U>
87 0 : scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
88 0 : if (ptr_)
89 0 : ptr_->AddRef();
90 0 : }
91 :
92 : // Move constructors.
93 0 : scoped_refptr(scoped_refptr<T>&& r) : ptr_(r.release()) {}
94 :
95 : template <typename U>
96 0 : scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.release()) {}
97 :
98 0 : ~scoped_refptr() {
99 0 : if (ptr_)
100 0 : ptr_->Release();
101 0 : }
102 :
103 0 : T* get() const { return ptr_; }
104 0 : operator T*() const { return ptr_; }
105 0 : T* operator->() const { return ptr_; }
106 :
107 : // Release a pointer.
108 : // The return value is the current pointer held by this object.
109 : // If this object holds a NULL pointer, the return value is NULL.
110 : // After this operation, this object will hold a NULL pointer,
111 : // and will not own the object any more.
112 0 : T* release() {
113 0 : T* retVal = ptr_;
114 0 : ptr_ = NULL;
115 0 : return retVal;
116 : }
117 :
118 0 : scoped_refptr<T>& operator=(T* p) {
119 : // AddRef first so that self assignment should work
120 0 : if (p)
121 0 : p->AddRef();
122 0 : if (ptr_ )
123 0 : ptr_ ->Release();
124 0 : ptr_ = p;
125 0 : return *this;
126 : }
127 :
128 0 : scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
129 0 : return *this = r.ptr_;
130 : }
131 :
132 : template <typename U>
133 0 : scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
134 0 : return *this = r.get();
135 : }
136 :
137 0 : scoped_refptr<T>& operator=(scoped_refptr<T>&& r) {
138 0 : scoped_refptr<T>(std::move(r)).swap(*this);
139 0 : return *this;
140 : }
141 :
142 : template <typename U>
143 : scoped_refptr<T>& operator=(scoped_refptr<U>&& r) {
144 : scoped_refptr<T>(std::move(r)).swap(*this);
145 : return *this;
146 : }
147 :
148 0 : void swap(T** pp) {
149 0 : T* p = ptr_;
150 0 : ptr_ = *pp;
151 0 : *pp = p;
152 0 : }
153 :
154 0 : void swap(scoped_refptr<T>& r) {
155 0 : swap(&r.ptr_);
156 0 : }
157 :
158 : protected:
159 : T* ptr_;
160 : };
161 :
162 : } // namespace rtc
163 :
164 : #endif // WEBRTC_BASE_SCOPED_REF_PTR_H_
|