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