]>
git.saurik.com Git - apple/javascriptcore.git/blob - wtf/PassRefPtr.h
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
*);
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.
39 void derefIfNotNull(T
* ptr
)
41 if (UNLIKELY(ptr
!= 0))
45 template<typename T
> class PassRefPtr
{
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
53 PassRefPtr(const PassRefPtr
& o
) : m_ptr(o
.releaseRef()) {}
54 template <typename U
> PassRefPtr(const PassRefPtr
<U
>& o
) : m_ptr(o
.releaseRef()) { }
56 ALWAYS_INLINE
~PassRefPtr() { derefIfNotNull
<T
>(m_ptr
); }
59 PassRefPtr(const RefPtr
<U
>& o
) : m_ptr(o
.get()) { if (T
* ptr
= m_ptr
) ptr
->ref(); }
61 T
* get() const { return m_ptr
; }
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
; }
66 T
& operator*() const { return *m_ptr
; }
67 T
* operator->() const { return m_ptr
; }
69 bool operator!() const { return !m_ptr
; }
71 // This conversion operator allows implicit conversion to bool but not to other integer types.
72 typedef T
* (PassRefPtr::*UnspecifiedBoolType
);
73 operator UnspecifiedBoolType() const { return m_ptr
? &PassRefPtr::m_ptr
: 0; }
75 PassRefPtr
& operator=(T
*);
76 PassRefPtr
& operator=(const PassRefPtr
&);
77 template <typename U
> PassRefPtr
& operator=(const PassRefPtr
<U
>&);
78 template <typename U
> PassRefPtr
& operator=(const RefPtr
<U
>&);
80 friend PassRefPtr adoptRef
<T
>(T
*);
82 // adopting constructor
83 PassRefPtr(T
* ptr
, bool) : m_ptr(ptr
) {}
87 // NonNullPassRefPtr: Optimized for passing non-null pointers. A NonNullPassRefPtr
88 // begins life non-null, and can only become null through a call to releaseRef()
91 // FIXME: NonNullPassRefPtr could just inherit from PassRefPtr. However,
92 // if we use inheritance, GCC's optimizer fails to realize that destruction
93 // of a released NonNullPassRefPtr is a no-op. So, for now, just copy the
94 // most important code from PassRefPtr.
95 template <typename T
> class NonNullPassRefPtr
{
97 NonNullPassRefPtr(T
* ptr
)
104 template <class U
> NonNullPassRefPtr(const RefPtr
<U
>& o
)
111 NonNullPassRefPtr(const NonNullPassRefPtr
& o
)
112 : m_ptr(o
.releaseRef())
117 template <class U
> NonNullPassRefPtr(const NonNullPassRefPtr
<U
>& o
)
118 : m_ptr(o
.releaseRef())
123 template <class U
> NonNullPassRefPtr(const PassRefPtr
<U
>& o
)
124 : m_ptr(o
.releaseRef())
129 ALWAYS_INLINE
~NonNullPassRefPtr() { derefIfNotNull(m_ptr
); }
131 T
* get() const { return m_ptr
; }
133 void clear() { derefIfNotNull(m_ptr
); m_ptr
= 0; }
134 T
* releaseRef() const { T
* tmp
= m_ptr
; m_ptr
= 0; return tmp
; }
136 T
& operator*() const { return *m_ptr
; }
137 T
* operator->() const { return m_ptr
; }
143 template <typename T
> template <typename U
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const RefPtr
<U
>& o
)
155 template <typename T
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(T
* optr
)
166 template <typename T
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const PassRefPtr
<T
>& ref
)
169 m_ptr
= ref
.releaseRef();
175 template <typename T
> template <typename U
> inline PassRefPtr
<T
>& PassRefPtr
<T
>::operator=(const PassRefPtr
<U
>& ref
)
178 m_ptr
= ref
.releaseRef();
184 template <typename T
, typename U
> inline bool operator==(const PassRefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
186 return a
.get() == b
.get();
189 template <typename T
, typename U
> inline bool operator==(const PassRefPtr
<T
>& a
, const RefPtr
<U
>& b
)
191 return a
.get() == b
.get();
194 template <typename T
, typename U
> inline bool operator==(const RefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
196 return a
.get() == b
.get();
199 template <typename T
, typename U
> inline bool operator==(const PassRefPtr
<T
>& a
, U
* b
)
204 template <typename T
, typename U
> inline bool operator==(T
* a
, const PassRefPtr
<U
>& b
)
209 template <typename T
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
211 return a
.get() != b
.get();
214 template <typename T
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, const RefPtr
<U
>& b
)
216 return a
.get() != b
.get();
219 template <typename T
, typename U
> inline bool operator!=(const RefPtr
<T
>& a
, const PassRefPtr
<U
>& b
)
221 return a
.get() != b
.get();
224 template <typename T
, typename U
> inline bool operator!=(const PassRefPtr
<T
>& a
, U
* b
)
229 template <typename T
, typename U
> inline bool operator!=(T
* a
, const PassRefPtr
<U
>& b
)
234 template <typename T
> inline PassRefPtr
<T
> adoptRef(T
* p
)
236 return PassRefPtr
<T
>(p
, true);
239 template <typename T
, typename U
> inline PassRefPtr
<T
> static_pointer_cast(const PassRefPtr
<U
>& p
)
241 return adoptRef(static_cast<T
*>(p
.releaseRef()));
244 template <typename T
, typename U
> inline PassRefPtr
<T
> const_pointer_cast(const PassRefPtr
<U
>& p
)
246 return adoptRef(const_cast<T
*>(p
.releaseRef()));
249 template <typename T
> inline T
* getPtr(const PassRefPtr
<T
>& p
)
256 using WTF::PassRefPtr
;
257 using WTF::NonNullPassRefPtr
;
259 using WTF::static_pointer_cast
;
260 using WTF::const_pointer_cast
;
262 #endif // WTF_PassRefPtr_h