]> git.saurik.com Git - apple/javascriptcore.git/blob - wtf/RefPtr.h
JavaScriptCore-466.1.6.tar.gz
[apple/javascriptcore.git] / wtf / RefPtr.h
1 // -*- mode: c++; c-basic-offset: 4 -*-
2 /*
3 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22 #ifndef WTF_RefPtr_h
23 #define WTF_RefPtr_h
24
25 #include <algorithm>
26 #include "AlwaysInline.h"
27
28 namespace WTF {
29
30 enum PlacementNewAdoptType { PlacementNewAdopt };
31
32 template <typename T> class PassRefPtr;
33
34 template <typename T> class RefPtr {
35 public:
36 RefPtr() : m_ptr(0) {}
37 RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
38 RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); }
39 // see comment in PassRefPtr.h for why this takes const reference
40 template <typename U> RefPtr(const PassRefPtr<U>&);
41
42 // Special constructor for cases where we overwrite an object in place.
43 RefPtr(PlacementNewAdoptType) { }
44
45 ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
46
47 template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
48
49 T* get() const { return m_ptr; }
50
51 void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
52 PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
53
54 T& operator*() const { return *m_ptr; }
55 ALWAYS_INLINE T *operator->() const { return m_ptr; }
56
57 bool operator!() const { return !m_ptr; }
58
59 // This conversion operator allows implicit conversion to bool but not to other integer types.
60 typedef T* RefPtr::*UnspecifiedBoolType;
61 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
62
63 RefPtr& operator=(const RefPtr&);
64 RefPtr& operator=(T*);
65 RefPtr& operator=(const PassRefPtr<T>&);
66 template <typename U> RefPtr& operator=(const RefPtr<U>&);
67 template <typename U> RefPtr& operator=(const PassRefPtr<U>&);
68
69 void swap(RefPtr&);
70
71 private:
72 T* m_ptr;
73 };
74
75 template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o)
76 : m_ptr(o.releaseRef())
77 {
78 }
79
80 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
81 {
82 T* optr = o.get();
83 if (optr)
84 optr->ref();
85 T* ptr = m_ptr;
86 m_ptr = optr;
87 if (ptr)
88 ptr->deref();
89 return *this;
90 }
91
92 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
93 {
94 T* optr = o.get();
95 if (optr)
96 optr->ref();
97 T* ptr = m_ptr;
98 m_ptr = optr;
99 if (ptr)
100 ptr->deref();
101 return *this;
102 }
103
104 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
105 {
106 if (optr)
107 optr->ref();
108 T* ptr = m_ptr;
109 m_ptr = optr;
110 if (ptr)
111 ptr->deref();
112 return *this;
113 }
114
115 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
116 {
117 T* ptr = m_ptr;
118 m_ptr = o.releaseRef();
119 if (ptr)
120 ptr->deref();
121 return *this;
122 }
123
124 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o)
125 {
126 T* ptr = m_ptr;
127 m_ptr = o.releaseRef();
128 if (ptr)
129 ptr->deref();
130 return *this;
131 }
132
133 template <class T> inline void RefPtr<T>::swap(RefPtr<T>& o)
134 {
135 std::swap(m_ptr, o.m_ptr);
136 }
137
138 template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b)
139 {
140 a.swap(b);
141 }
142
143 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b)
144 {
145 return a.get() == b.get();
146 }
147
148 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b)
149 {
150 return a.get() == b;
151 }
152
153 template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b)
154 {
155 return a == b.get();
156 }
157
158 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b)
159 {
160 return a.get() != b.get();
161 }
162
163 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b)
164 {
165 return a.get() != b;
166 }
167
168 template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b)
169 {
170 return a != b.get();
171 }
172
173 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p)
174 {
175 return RefPtr<T>(static_cast<T*>(p.get()));
176 }
177
178 template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p)
179 {
180 return RefPtr<T>(const_cast<T*>(p.get()));
181 }
182
183 template <typename T> inline T* getPtr(const RefPtr<T>& p)
184 {
185 return p.get();
186 }
187
188 } // namespace WTF
189
190 using WTF::RefPtr;
191 using WTF::static_pointer_cast;
192 using WTF::const_pointer_cast;
193
194 #endif // WTF_RefPtr_h