]> git.saurik.com Git - apple/javascriptcore.git/blame - wtf/RefPtr.h
JavaScriptCore-521.tar.gz
[apple/javascriptcore.git] / wtf / RefPtr.h
CommitLineData
b37bf2e1 1/*
9dae56ea 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
b37bf2e1
A
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
27namespace WTF {
28
29 enum PlacementNewAdoptType { PlacementNewAdopt };
30
31 template <typename T> class PassRefPtr;
32
9dae56ea
A
33 enum HashTableDeletedValueType { HashTableDeletedValue };
34
b37bf2e1
A
35 template <typename T> class RefPtr {
36 public:
9dae56ea 37 RefPtr() : m_ptr(0) { }
b37bf2e1
A
38 RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
39 RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); }
40 // see comment in PassRefPtr.h for why this takes const reference
41 template <typename U> RefPtr(const PassRefPtr<U>&);
42
43 // Special constructor for cases where we overwrite an object in place.
44 RefPtr(PlacementNewAdoptType) { }
45
9dae56ea
A
46 // Hash table deleted values, which are only constructed and never copied or destroyed.
47 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
48 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
49
b37bf2e1
A
50 ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
51
52 template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
53
54 T* get() const { return m_ptr; }
55
56 void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
57 PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
58
59 T& operator*() const { return *m_ptr; }
9dae56ea 60 ALWAYS_INLINE T* operator->() const { return m_ptr; }
b37bf2e1
A
61
62 bool operator!() const { return !m_ptr; }
63
64 // This conversion operator allows implicit conversion to bool but not to other integer types.
9dae56ea
A
65#if COMPILER(WINSCW)
66 operator bool() const { return m_ptr; }
67#else
b37bf2e1
A
68 typedef T* RefPtr::*UnspecifiedBoolType;
69 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
9dae56ea 70#endif
b37bf2e1
A
71
72 RefPtr& operator=(const RefPtr&);
73 RefPtr& operator=(T*);
74 RefPtr& operator=(const PassRefPtr<T>&);
75 template <typename U> RefPtr& operator=(const RefPtr<U>&);
76 template <typename U> RefPtr& operator=(const PassRefPtr<U>&);
77
78 void swap(RefPtr&);
79
80 private:
9dae56ea
A
81 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
82
b37bf2e1
A
83 T* m_ptr;
84 };
85
86 template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o)
87 : m_ptr(o.releaseRef())
88 {
89 }
90
91 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
92 {
93 T* optr = o.get();
94 if (optr)
95 optr->ref();
96 T* ptr = m_ptr;
97 m_ptr = optr;
98 if (ptr)
99 ptr->deref();
100 return *this;
101 }
102
103 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
104 {
105 T* optr = o.get();
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=(T* optr)
116 {
117 if (optr)
118 optr->ref();
119 T* ptr = m_ptr;
120 m_ptr = optr;
121 if (ptr)
122 ptr->deref();
123 return *this;
124 }
125
126 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
127 {
128 T* ptr = m_ptr;
129 m_ptr = o.releaseRef();
130 if (ptr)
131 ptr->deref();
132 return *this;
133 }
134
135 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o)
136 {
137 T* ptr = m_ptr;
138 m_ptr = o.releaseRef();
139 if (ptr)
140 ptr->deref();
141 return *this;
142 }
143
144 template <class T> inline void RefPtr<T>::swap(RefPtr<T>& o)
145 {
146 std::swap(m_ptr, o.m_ptr);
147 }
148
149 template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b)
150 {
151 a.swap(b);
152 }
153
154 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b)
155 {
156 return a.get() == b.get();
157 }
158
159 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b)
160 {
161 return a.get() == b;
162 }
163
164 template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b)
165 {
166 return a == b.get();
167 }
168
169 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b)
170 {
171 return a.get() != b.get();
172 }
173
174 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b)
175 {
176 return a.get() != b;
177 }
178
179 template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b)
180 {
181 return a != b.get();
182 }
183
184 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p)
185 {
186 return RefPtr<T>(static_cast<T*>(p.get()));
187 }
188
189 template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p)
190 {
191 return RefPtr<T>(const_cast<T*>(p.get()));
192 }
193
194 template <typename T> inline T* getPtr(const RefPtr<T>& p)
195 {
196 return p.get();
197 }
198
199} // namespace WTF
200
201using WTF::RefPtr;
202using WTF::static_pointer_cast;
203using WTF::const_pointer_cast;
204
205#endif // WTF_RefPtr_h