]>
git.saurik.com Git - apple/javascriptcore.git/blob - wtf/PassRefPtr.h
2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 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"
29 template<typename T
> class RefPtr
;
30 template<typename T
> class PassRefPtr
;
31 template<typename T
> PassRefPtr
<T
> adoptRef(T
*);
33 inline void adopted(const void*) { }
37 #define REF_DEREF_INLINE ALWAYS_INLINE
39 // Using ALWAYS_INLINE broke the Qt build. This may be a GCC bug.
40 // See https://bugs.webkit.org/show_bug.cgi?id=37253 for details.
41 #define REF_DEREF_INLINE inline
44 // No inlining for WINSCW compiler to prevent the compiler agressively resolving
45 // T::ref() and T::deref(), which will fail compiling when PassRefPtr<T> is used as
46 // a class member or function arguments before T is defined.
47 #define REF_DEREF_INLINE
50 template<typename T
> REF_DEREF_INLINE
void refIfNotNull(T
* ptr
)
56 template<typename T
> REF_DEREF_INLINE
void derefIfNotNull(T
* ptr
)
62 #undef REF_DEREF_INLINE
64 template<typename T
> class PassRefPtr
{
66 PassRefPtr() : m_ptr(0) { }
67 PassRefPtr(T
* ptr
) : m_ptr(ptr
) { refIfNotNull(ptr
); }
68 // It somewhat breaks the type system to allow transfer of ownership out of
69 // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
70 // temporaries, and we don't have a need to use real const PassRefPtrs anyway.
71 PassRefPtr(const PassRefPtr
& o
) : m_ptr(o
.leakRef()) { }
72 template<typename U
> PassRefPtr(const PassRefPtr
<U
>& o
) : m_ptr(o
.leakRef()) { }
74 ALWAYS_INLINE
~PassRefPtr() { derefIfNotNull(m_ptr
); }
76 template<typename U
> PassRefPtr(const RefPtr
<U
>&);
78 T
* get() const { return m_ptr
; }
81 T
* leakRef() const WARN_UNUSED_RETURN
;
83 T
& operator*() const { return *m_ptr
; }
84 T
* operator->() const { return m_ptr
; }
86 bool operator!() const { return !m_ptr
; }
88 // This conversion operator allows implicit conversion to bool but not to other integer types.
89 typedef T
* (PassRefPtr::*UnspecifiedBoolType
);
90 operator UnspecifiedBoolType() const { return m_ptr
? &PassRefPtr::m_ptr
: 0; }
92 PassRefPtr
& operator=(T
*);
93 PassRefPtr
& operator=(const PassRefPtr
&);
95 PassRefPtr
& operator=(std::nullptr_t
) { clear(); return *this; }
97 template<typename U
> PassRefPtr
& operator=(const PassRefPtr
<U
>&);
98 template<typename U
> PassRefPtr
& operator=(const RefPtr
<U
>&);
100 friend PassRefPtr adoptRef
<T
>(T
*);
102 // FIXME: Remove releaseRef once we change all callers to call leakRef instead.
103 T
* releaseRef() const WARN_UNUSED_RETURN
{ return leakRef(); }
106 // adopting constructor
107 PassRefPtr(T
* ptr
, bool) : m_ptr(ptr
) { }
112 // NonNullPassRefPtr: Optimized for passing non-null pointers. A NonNullPassRefPtr
113 // begins life non-null, and can only become null through a call to leakRef()
116 // FIXME: NonNullPassRefPtr could just inherit from PassRefPtr. However,
117 // if we use inheritance, GCC's optimizer fails to realize that destruction
118 // of a released NonNullPassRefPtr is a no-op. So, for now, just copy the
119 // most important code from PassRefPtr.
120 template<typename T
> class NonNullPassRefPtr
{
122 NonNullPassRefPtr(T
* ptr
)
129 template<typename U
> NonNullPassRefPtr(const RefPtr
<U
>& o
)
136 NonNullPassRefPtr(const NonNullPassRefPtr
& o
)
142 template<typename U
> NonNullPassRefPtr(const NonNullPassRefPtr
<U
>& o
)
148 template<typename U
> NonNullPassRefPtr(const PassRefPtr
<U
>& o
)
154 ALWAYS_INLINE
~NonNullPassRefPtr() { derefIfNotNull(m_ptr
); }
156 T
* get() const { return m_ptr
; }
159 T
* leakRef() const WARN_UNUSED_RETURN
{ T
* tmp
= m_ptr
; m_ptr
= 0; return tmp
; }
161 T
& operator*() const { return *m_ptr
; }
162 T
* operator->() const { return m_ptr
; }
164 // FIXME: Remove releaseRef once we change all callers to call leakRef instead.
165 T
* releaseRef() const WARN_UNUSED_RETURN
{ return leakRef(); }
171 template<typename T
> template<typename U
> inline PassRefPtr
<T
>::PassRefPtr(const RefPtr
<U
>& o
)
178 template<typename T
> inline void PassRefPtr
<T
>::clear()
185 template<typename T
> inline T
* PassRefPtr
<T
>::leakRef() const
192 template<typename T
> template<typename U
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const RefPtr
<U
>& o
)
202 template<typename T
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(T
* optr
)
211 template<typename T
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const PassRefPtr
<T
>& ref
)
214 m_ptr
= ref
.leakRef();
219 template<typename T
> template<typename U
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const PassRefPtr
<U
>& ref
)
222 m_ptr
= ref
.leakRef();
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
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
254 return a
.get() != b
.get();
257 template<typename T
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, const RefPtr
<U
>& b
)
259 return a
.get() != b
.get();
262 template<typename T
, typename U
> inline bool operator!=(const RefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
264 return a
.get() != b
.get();
267 template<typename T
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, U
* b
)
272 template<typename T
, typename U
> inline bool operator!=(T
* a
, const PassRefPtr
<U
>& b
)
277 template<typename T
> inline PassRefPtr
<T
> adoptRef(T
* p
)
280 return PassRefPtr
<T
>(p
, true);
283 template<typename T
, typename U
> inline PassRefPtr
<T
> static_pointer_cast(const PassRefPtr
<U
>& p
)
285 return adoptRef(static_cast<T
*>(p
.leakRef()));
288 template<typename T
, typename U
> inline PassRefPtr
<T
> const_pointer_cast(const PassRefPtr
<U
>& p
)
290 return adoptRef(const_cast<T
*>(p
.leakRef()));
293 template<typename T
> inline T
* getPtr(const PassRefPtr
<T
>& p
)
298 template<typename T
> inline void NonNullPassRefPtr
<T
>::clear()
307 using WTF::PassRefPtr
;
308 using WTF::NonNullPassRefPtr
;
310 using WTF::static_pointer_cast
;
311 using WTF::const_pointer_cast
;
313 #endif // WTF_PassRefPtr_h