]> git.saurik.com Git - apple/javascriptcore.git/blob - wtf/PassRefPtr.h
c1dc309f4d79c436042817c928ff09c15e834943
[apple/javascriptcore.git] / wtf / PassRefPtr.h
1 /*
2 * Copyright (C) 2005, 2006, 2007 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_PassRefPtr_h
22 #define WTF_PassRefPtr_h
23
24 #include "AlwaysInline.h"
25
26 namespace WTF {
27
28 template<typename T> class RefPtr;
29 template<typename T> class PassRefPtr;
30 template <typename T> PassRefPtr<T> adoptRef(T*);
31
32 template<typename T> class PassRefPtr {
33 public:
34 PassRefPtr() : m_ptr(0) {}
35 PassRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
36 // It somewhat breaks the type system to allow transfer of ownership out of
37 // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
38 // temporaries, and we don't really have a need to use real const PassRefPtrs
39 // anyway.
40 PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
41 template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
42
43 ALWAYS_INLINE ~PassRefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
44
45 template <class U>
46 PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
47
48 T* get() const { return m_ptr; }
49
50 void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
51 T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
52
53 T& operator*() const { return *m_ptr; }
54 T* operator->() const { return m_ptr; }
55
56 bool operator!() const { return !m_ptr; }
57
58 // This conversion operator allows implicit conversion to bool but not to other integer types.
59 #if COMPILER(WINSCW)
60 operator bool() const { return m_ptr; }
61 #else
62 typedef T* PassRefPtr::*UnspecifiedBoolType;
63 operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; }
64 #endif
65 PassRefPtr& operator=(T*);
66 PassRefPtr& operator=(const PassRefPtr&);
67 template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&);
68 template <typename U> PassRefPtr& operator=(const RefPtr<U>&);
69
70 friend PassRefPtr adoptRef<T>(T*);
71 private:
72 // adopting constructor
73 PassRefPtr(T* ptr, bool) : m_ptr(ptr) {}
74 mutable T* m_ptr;
75 };
76
77 template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o)
78 {
79 T* optr = o.get();
80 if (optr)
81 optr->ref();
82 T* ptr = m_ptr;
83 m_ptr = optr;
84 if (ptr)
85 ptr->deref();
86 return *this;
87 }
88
89 template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
90 {
91 if (optr)
92 optr->ref();
93 T* ptr = m_ptr;
94 m_ptr = optr;
95 if (ptr)
96 ptr->deref();
97 return *this;
98 }
99
100 template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref)
101 {
102 T* ptr = m_ptr;
103 m_ptr = ref.releaseRef();
104 if (ptr)
105 ptr->deref();
106 return *this;
107 }
108
109 template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref)
110 {
111 T* ptr = m_ptr;
112 m_ptr = ref.releaseRef();
113 if (ptr)
114 ptr->deref();
115 return *this;
116 }
117
118 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b)
119 {
120 return a.get() == b.get();
121 }
122
123 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b)
124 {
125 return a.get() == b.get();
126 }
127
128 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b)
129 {
130 return a.get() == b.get();
131 }
132
133 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b)
134 {
135 return a.get() == b;
136 }
137
138 template <typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b)
139 {
140 return a == b.get();
141 }
142
143 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b)
144 {
145 return a.get() != b.get();
146 }
147
148 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b)
149 {
150 return a.get() != b.get();
151 }
152
153 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b)
154 {
155 return a.get() != b.get();
156 }
157
158 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b)
159 {
160 return a.get() != b;
161 }
162
163 template <typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b)
164 {
165 return a != b.get();
166 }
167
168 template <typename T> inline PassRefPtr<T> adoptRef(T* p)
169 {
170 return PassRefPtr<T>(p, true);
171 }
172
173 template <typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p)
174 {
175 return adoptRef(static_cast<T*>(p.releaseRef()));
176 }
177
178 template <typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p)
179 {
180 return adoptRef(const_cast<T*>(p.releaseRef()));
181 }
182
183 template <typename T> inline T* getPtr(const PassRefPtr<T>& p)
184 {
185 return p.get();
186 }
187
188 } // namespace WTF
189
190 using WTF::PassRefPtr;
191 using WTF::adoptRef;
192 using WTF::static_pointer_cast;
193 using WTF::const_pointer_cast;
194
195 #endif // WTF_PassRefPtr_h