]>
git.saurik.com Git - apple/javascriptcore.git/blob - wtf/PassRefPtr.h
25a93a4351e084ea7b651aad1e680ba1e83ac62e
2 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
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.
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.
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.
21 #ifndef WTF_PassRefPtr_h
22 #define WTF_PassRefPtr_h
24 #include "AlwaysInline.h"
28 template<typename T
> class RefPtr
;
29 template<typename T
> class PassRefPtr
;
30 template <typename T
> PassRefPtr
<T
> adoptRef(T
*);
33 // Remove inline for WINSCW compiler to prevent the compiler agressively resolving
34 // T::ref() and T::deref(), which will fail compiling when PassRefPtr<T> is used as
35 // a class member or function arguments before T is defined.
37 // [Qt]r57240 broke Qt build (might be a gcc bug)
38 // FIXME! See: https://bugs.webkit.org/show_bug.cgi?id=37253
47 void refIfNotNull(T
* ptr
)
53 // [Qt]r57240 broke Qt build (might be a gcc bug)
54 // FIXME! See: https://bugs.webkit.org/show_bug.cgi?id=37253
63 void derefIfNotNull(T
* ptr
)
69 template<typename T
> class PassRefPtr
{
71 PassRefPtr() : m_ptr(0) {}
72 PassRefPtr(T
* ptr
) : m_ptr(ptr
) { refIfNotNull(ptr
); }
73 // It somewhat breaks the type system to allow transfer of ownership out of
74 // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
75 // temporaries, and we don't really have a need to use real const PassRefPtrs
77 PassRefPtr(const PassRefPtr
& o
) : m_ptr(o
.releaseRef()) {}
78 template <typename U
> PassRefPtr(const PassRefPtr
<U
>& o
) : m_ptr(o
.releaseRef()) { }
80 ALWAYS_INLINE
~PassRefPtr() { derefIfNotNull(m_ptr
); }
83 PassRefPtr(const RefPtr
<U
>& o
) : m_ptr(o
.get()) { T
* ptr
= m_ptr
; refIfNotNull(ptr
); }
85 T
* get() const { return m_ptr
; }
87 void clear() { T
* ptr
= m_ptr
; derefIfNotNull(ptr
); m_ptr
= 0; }
88 T
* releaseRef() const { T
* tmp
= m_ptr
; m_ptr
= 0; return tmp
; }
90 T
& operator*() const { return *m_ptr
; }
91 T
* operator->() const { return m_ptr
; }
93 bool operator!() const { return !m_ptr
; }
95 // This conversion operator allows implicit conversion to bool but not to other integer types.
96 typedef T
* (PassRefPtr::*UnspecifiedBoolType
);
97 operator UnspecifiedBoolType() const { return m_ptr
? &PassRefPtr::m_ptr
: 0; }
99 PassRefPtr
& operator=(T
*);
100 PassRefPtr
& operator=(const PassRefPtr
&);
101 template <typename U
> PassRefPtr
& operator=(const PassRefPtr
<U
>&);
102 template <typename U
> PassRefPtr
& operator=(const RefPtr
<U
>&);
104 friend PassRefPtr adoptRef
<T
>(T
*);
106 // adopting constructor
107 PassRefPtr(T
* ptr
, bool) : m_ptr(ptr
) {}
111 // NonNullPassRefPtr: Optimized for passing non-null pointers. A NonNullPassRefPtr
112 // begins life non-null, and can only become null through a call to releaseRef()
115 // FIXME: NonNullPassRefPtr could just inherit from PassRefPtr. However,
116 // if we use inheritance, GCC's optimizer fails to realize that destruction
117 // of a released NonNullPassRefPtr is a no-op. So, for now, just copy the
118 // most important code from PassRefPtr.
119 template <typename T
> class NonNullPassRefPtr
{
121 NonNullPassRefPtr(T
* ptr
)
128 template <class U
> NonNullPassRefPtr(const RefPtr
<U
>& o
)
135 NonNullPassRefPtr(const NonNullPassRefPtr
& o
)
136 : m_ptr(o
.releaseRef())
141 template <class U
> NonNullPassRefPtr(const NonNullPassRefPtr
<U
>& o
)
142 : m_ptr(o
.releaseRef())
147 template <class U
> NonNullPassRefPtr(const PassRefPtr
<U
>& o
)
148 : m_ptr(o
.releaseRef())
153 ALWAYS_INLINE
~NonNullPassRefPtr() { derefIfNotNull(m_ptr
); }
155 T
* get() const { return m_ptr
; }
157 void clear() { derefIfNotNull(m_ptr
); m_ptr
= 0; }
158 T
* releaseRef() const { T
* tmp
= m_ptr
; m_ptr
= 0; return tmp
; }
160 T
& operator*() const { return *m_ptr
; }
161 T
* operator->() const { return m_ptr
; }
167 template <typename T
> template <typename U
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const RefPtr
<U
>& o
)
177 template <typename T
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(T
* optr
)
186 template <typename T
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const PassRefPtr
<T
>& ref
)
189 m_ptr
= ref
.releaseRef();
194 template <typename T
> template <typename U
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const PassRefPtr
<U
>& ref
)
197 m_ptr
= ref
.releaseRef();
202 template <typename T
, typename U
> inline bool operator==(const PassRefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
204 return a
.get() == b
.get();
207 template <typename T
, typename U
> inline bool operator==(const PassRefPtr
<T
>& a
, const RefPtr
<U
>& b
)
209 return a
.get() == b
.get();
212 template <typename T
, typename U
> inline bool operator==(const RefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
214 return a
.get() == b
.get();
217 template <typename T
, typename U
> inline bool operator==(const PassRefPtr
<T
>& a
, U
* b
)
222 template <typename T
, typename U
> inline bool operator==(T
* a
, const PassRefPtr
<U
>& b
)
227 template <typename T
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
229 return a
.get() != b
.get();
232 template <typename T
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, const RefPtr
<U
>& b
)
234 return a
.get() != b
.get();
237 template <typename T
, typename U
> inline bool operator!=(const RefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
239 return a
.get() != b
.get();
242 template <typename T
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, U
* b
)
247 template <typename T
, typename U
> inline bool operator!=(T
* a
, const PassRefPtr
<U
>& b
)
252 template <typename T
> inline PassRefPtr
<T
> adoptRef(T
* p
)
254 return PassRefPtr
<T
>(p
, true);
257 template <typename T
, typename U
> inline PassRefPtr
<T
> static_pointer_cast(const PassRefPtr
<U
>& p
)
259 return adoptRef(static_cast<T
*>(p
.releaseRef()));
262 template <typename T
, typename U
> inline PassRefPtr
<T
> const_pointer_cast(const PassRefPtr
<U
>& p
)
264 return adoptRef(const_cast<T
*>(p
.releaseRef()));
267 template <typename T
> inline T
* getPtr(const PassRefPtr
<T
>& p
)
274 using WTF::PassRefPtr
;
275 using WTF::NonNullPassRefPtr
;
277 using WTF::static_pointer_cast
;
278 using WTF::const_pointer_cast
;
280 #endif // WTF_PassRefPtr_h