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