]> git.saurik.com Git - apple/javascriptcore.git/blob - wtf/RefPtr.h
eed793329a472c242bf1c34e6eda83e2b675e43e
[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 // RefPtr and PassRefPtr are documented at http://webkit.org/coding/RefPtr.html
22
23 #ifndef WTF_RefPtr_h
24 #define WTF_RefPtr_h
25
26 #include <algorithm>
27 #include "AlwaysInline.h"
28 #include "FastAllocBase.h"
29 #include "PassRefPtr.h"
30
31 namespace WTF {
32
33 enum PlacementNewAdoptType { PlacementNewAdopt };
34
35 template <typename T> class PassRefPtr;
36 template <typename T> class NonNullPassRefPtr;
37
38 enum HashTableDeletedValueType { HashTableDeletedValue };
39
40 template <typename T> class RefPtr : public FastAllocBase {
41 public:
42 RefPtr() : m_ptr(0) { }
43 RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
44 RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { T* ptr = m_ptr; refIfNotNull(ptr); }
45 // see comment in PassRefPtr.h for why this takes const reference
46 template <typename U> RefPtr(const PassRefPtr<U>&);
47 template <typename U> RefPtr(const NonNullPassRefPtr<U>&);
48
49 // Special constructor for cases where we overwrite an object in place.
50 RefPtr(PlacementNewAdoptType) { }
51
52 // Hash table deleted values, which are only constructed and never copied or destroyed.
53 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
54 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
55
56 ~RefPtr() { derefIfNotNull(m_ptr); }
57
58 template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); }
59
60 T* get() const { return m_ptr; }
61
62 void clear() { derefIfNotNull(m_ptr); m_ptr = 0; }
63 PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
64
65 T& operator*() const { return *m_ptr; }
66 ALWAYS_INLINE T* operator->() const { return m_ptr; }
67
68 bool operator!() const { return !m_ptr; }
69
70 // This conversion operator allows implicit conversion to bool but not to other integer types.
71 typedef T* (RefPtr::*UnspecifiedBoolType);
72 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
73
74 RefPtr& operator=(const RefPtr&);
75 RefPtr& operator=(T*);
76 RefPtr& operator=(const PassRefPtr<T>&);
77 RefPtr& operator=(const NonNullPassRefPtr<T>&);
78 template <typename U> RefPtr& operator=(const RefPtr<U>&);
79 template <typename U> RefPtr& operator=(const PassRefPtr<U>&);
80 template <typename U> RefPtr& operator=(const NonNullPassRefPtr<U>&);
81
82 void swap(RefPtr&);
83
84 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
85
86 private:
87 T* m_ptr;
88 };
89
90 template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o)
91 : m_ptr(o.releaseRef())
92 {
93 }
94
95 template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const NonNullPassRefPtr<U>& o)
96 : m_ptr(o.releaseRef())
97 {
98 }
99
100 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
101 {
102 T* optr = o.get();
103 refIfNotNull(optr);
104 T* ptr = m_ptr;
105 m_ptr = optr;
106 derefIfNotNull(ptr);
107 return *this;
108 }
109
110 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
111 {
112 T* optr = o.get();
113 refIfNotNull(optr);
114 T* ptr = m_ptr;
115 m_ptr = optr;
116 derefIfNotNull(ptr);
117 return *this;
118 }
119
120 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
121 {
122 refIfNotNull(optr);
123 T* ptr = m_ptr;
124 m_ptr = optr;
125 derefIfNotNull(ptr);
126 return *this;
127 }
128
129 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
130 {
131 T* ptr = m_ptr;
132 m_ptr = o.releaseRef();
133 derefIfNotNull(ptr);
134 return *this;
135 }
136
137 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<T>& o)
138 {
139 T* ptr = m_ptr;
140 m_ptr = o.releaseRef();
141 derefIfNotNull(ptr);
142 return *this;
143 }
144
145 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o)
146 {
147 T* ptr = m_ptr;
148 m_ptr = o.releaseRef();
149 derefIfNotNull(ptr);
150 return *this;
151 }
152
153 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<U>& o)
154 {
155 T* ptr = m_ptr;
156 m_ptr = o.releaseRef();
157 derefIfNotNull(ptr);
158 return *this;
159 }
160
161 template <class T> inline void RefPtr<T>::swap(RefPtr<T>& o)
162 {
163 std::swap(m_ptr, o.m_ptr);
164 }
165
166 template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b)
167 {
168 a.swap(b);
169 }
170
171 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b)
172 {
173 return a.get() == b.get();
174 }
175
176 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b)
177 {
178 return a.get() == b;
179 }
180
181 template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b)
182 {
183 return a == b.get();
184 }
185
186 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b)
187 {
188 return a.get() != b.get();
189 }
190
191 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b)
192 {
193 return a.get() != b;
194 }
195
196 template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b)
197 {
198 return a != b.get();
199 }
200
201 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p)
202 {
203 return RefPtr<T>(static_cast<T*>(p.get()));
204 }
205
206 template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p)
207 {
208 return RefPtr<T>(const_cast<T*>(p.get()));
209 }
210
211 template <typename T> inline T* getPtr(const RefPtr<T>& p)
212 {
213 return p.get();
214 }
215
216 } // namespace WTF
217
218 using WTF::RefPtr;
219 using WTF::static_pointer_cast;
220 using WTF::const_pointer_cast;
221
222 #endif // WTF_RefPtr_h