source: webkit/trunk/JavaScriptCore/wtf/PassRefPtr.h@ 47667

Last change on this file since 47667 was 47592, checked in by [email protected], 16 years ago

2009-08-20 Yongjun Zhang <[email protected]>

Reviewed by Eric Seidel.

https://bugs.webkit.org/show_bug.cgi?id=28054

Use a helper function to work around winscw compiler forward declaration bug
regarding templated classes.

Add parenthesis around (PassRefPtr::*UnspecifiedBoolType) to make winscw compiler
work with the default UnSpecifiedBoolType() operator, which removes the winscw
specific bool cast hack.

  • wtf/PassRefPtr.h: (WTF::derefIfNotNull): (WTF::PassRefPtr::~PassRefPtr):
  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
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
26namespace WTF {
27
28 template<typename T> class RefPtr;
29 template<typename T> class PassRefPtr;
30 template <typename T> PassRefPtr<T> adoptRef(T*);
31
32 // Remove inline for winscw compiler to prevent the compiler agressively resolving
33 // T::deref(), which will fail compiling when PassRefPtr<T> is used as class member
34 // or function arguments before T is defined.
35 template<typename T>
36#if !COMPILER(WINSCW)
37 inline
38#endif
39 void derefIfNotNull(T* ptr)
40 {
41 if (UNLIKELY(ptr != 0))
42 ptr->deref();
43 }
44
45 template<typename T> class PassRefPtr {
46 public:
47 PassRefPtr() : m_ptr(0) {}
48 PassRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
49 // It somewhat breaks the type system to allow transfer of ownership out of
50 // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
51 // temporaries, and we don't really have a need to use real const PassRefPtrs
52 // anyway.
53 PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
54 template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
55
56 ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull<T>(m_ptr); }
57
58 template <class U>
59 PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
60
61 T* get() const { return m_ptr; }
62
63 void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
64 T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
65
66 T& operator*() const { return *m_ptr; }
67 T* operator->() const { return m_ptr; }
68
69 bool operator!() const { return !m_ptr; }
70
71 // This conversion operator allows implicit conversion to bool but not to other integer types.
72 // Parenthesis is needed for winscw compiler to resolve class qualifier in this case.
73 typedef T* (PassRefPtr::*UnspecifiedBoolType);
74 operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; }
75
76 PassRefPtr& operator=(T*);
77 PassRefPtr& operator=(const PassRefPtr&);
78 template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&);
79 template <typename U> PassRefPtr& operator=(const RefPtr<U>&);
80
81 friend PassRefPtr adoptRef<T>(T*);
82 private:
83 // adopting constructor
84 PassRefPtr(T* ptr, bool) : m_ptr(ptr) {}
85 mutable T* m_ptr;
86 };
87
88 template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o)
89 {
90 T* optr = o.get();
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=(T* optr)
101 {
102 if (optr)
103 optr->ref();
104 T* ptr = m_ptr;
105 m_ptr = optr;
106 if (ptr)
107 ptr->deref();
108 return *this;
109 }
110
111 template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref)
112 {
113 T* ptr = m_ptr;
114 m_ptr = ref.releaseRef();
115 if (ptr)
116 ptr->deref();
117 return *this;
118 }
119
120 template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref)
121 {
122 T* ptr = m_ptr;
123 m_ptr = ref.releaseRef();
124 if (ptr)
125 ptr->deref();
126 return *this;
127 }
128
129 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b)
130 {
131 return a.get() == b.get();
132 }
133
134 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b)
135 {
136 return a.get() == b.get();
137 }
138
139 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b)
140 {
141 return a.get() == b.get();
142 }
143
144 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b)
145 {
146 return a.get() == b;
147 }
148
149 template <typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b)
150 {
151 return a == b.get();
152 }
153
154 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b)
155 {
156 return a.get() != b.get();
157 }
158
159 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b)
160 {
161 return a.get() != b.get();
162 }
163
164 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b)
165 {
166 return a.get() != b.get();
167 }
168
169 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b)
170 {
171 return a.get() != b;
172 }
173
174 template <typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b)
175 {
176 return a != b.get();
177 }
178
179 template <typename T> inline PassRefPtr<T> adoptRef(T* p)
180 {
181 return PassRefPtr<T>(p, true);
182 }
183
184 template <typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p)
185 {
186 return adoptRef(static_cast<T*>(p.releaseRef()));
187 }
188
189 template <typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p)
190 {
191 return adoptRef(const_cast<T*>(p.releaseRef()));
192 }
193
194 template <typename T> inline T* getPtr(const PassRefPtr<T>& p)
195 {
196 return p.get();
197 }
198
199} // namespace WTF
200
201using WTF::PassRefPtr;
202using WTF::adoptRef;
203using WTF::static_pointer_cast;
204using WTF::const_pointer_cast;
205
206#endif // WTF_PassRefPtr_h
Note: See TracBrowser for help on using the repository browser.