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