blob: ae1ab0f230ee8bcf9d88b5d87fd502310dd6acd2 [file] [log] [blame]
henrike@webrtc.org0e118e72013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2011, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28// Originally these classes are from Chromium.
29// http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/ref_counted.h?view=markup
30
31//
32// A smart pointer class for reference counted objects. Use this class instead
33// of calling AddRef and Release manually on a reference counted object to
34// avoid common memory leaks caused by forgetting to Release an object
35// reference. Sample usage:
36//
37// class MyFoo : public RefCounted<MyFoo> {
38// ...
39// };
40//
41// void some_function() {
42// scoped_refptr<MyFoo> foo = new MyFoo();
43// foo->Method(param);
44// // |foo| is released when this function returns
45// }
46//
47// void some_other_function() {
48// scoped_refptr<MyFoo> foo = new MyFoo();
49// ...
50// foo = NULL; // explicitly releases |foo|
51// ...
52// if (foo)
53// foo->Method(param);
54// }
55//
56// The above examples show how scoped_refptr<T> acts like a pointer to T.
57// Given two scoped_refptr<T> classes, it is also possible to exchange
58// references between the two objects, like so:
59//
60// {
61// scoped_refptr<MyFoo> a = new MyFoo();
62// scoped_refptr<MyFoo> b;
63//
64// b.swap(a);
65// // now, |b| references the MyFoo object, and |a| references NULL.
66// }
67//
68// To make both |a| and |b| in the above example reference the same MyFoo
69// object, simply use the assignment operator:
70//
71// {
72// scoped_refptr<MyFoo> a = new MyFoo();
73// scoped_refptr<MyFoo> b;
74//
75// b = a;
76// // now, |a| and |b| each own a reference to the same MyFoo object.
77// }
78//
79
80#ifndef TALK_BASE_SCOPED_REF_PTR_H_
81#define TALK_BASE_SCOPED_REF_PTR_H_
82
buildbot@webrtc.orgb77e82e2014-04-29 17:55:26 +000083#include <stddef.h>
84
henrike@webrtc.org0e118e72013-07-10 00:45:36 +000085namespace talk_base {
86
87template <class T>
88class scoped_refptr {
89 public:
90 scoped_refptr() : ptr_(NULL) {
91 }
92
93 scoped_refptr(T* p) : ptr_(p) {
94 if (ptr_)
95 ptr_->AddRef();
96 }
97
98 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
99 if (ptr_)
100 ptr_->AddRef();
101 }
102
103 template <typename U>
104 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
105 if (ptr_)
106 ptr_->AddRef();
107 }
108
109 ~scoped_refptr() {
110 if (ptr_)
111 ptr_->Release();
112 }
113
114 T* get() const { return ptr_; }
115 operator T*() const { return ptr_; }
116 T* operator->() const { return ptr_; }
117
118 // Release a pointer.
119 // The return value is the current pointer held by this object.
120 // If this object holds a NULL pointer, the return value is NULL.
121 // After this operation, this object will hold a NULL pointer,
122 // and will not own the object any more.
123 T* release() {
124 T* retVal = ptr_;
125 ptr_ = NULL;
126 return retVal;
127 }
128
129 scoped_refptr<T>& operator=(T* p) {
130 // AddRef first so that self assignment should work
131 if (p)
132 p->AddRef();
133 if (ptr_ )
134 ptr_ ->Release();
135 ptr_ = p;
136 return *this;
137 }
138
139 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
140 return *this = r.ptr_;
141 }
142
143 template <typename U>
144 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
145 return *this = r.get();
146 }
147
148 void swap(T** pp) {
149 T* p = ptr_;
150 ptr_ = *pp;
151 *pp = p;
152 }
153
154 void swap(scoped_refptr<T>& r) {
155 swap(&r.ptr_);
156 }
157
158 protected:
159 T* ptr_;
160};
161
162} // namespace talk_base
163
164#endif // TALK_BASE_SCOPED_REF_PTR_H_