2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 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 // RefPtr and PassRefPtr are documented at http://webkit.org/coding/RefPtr.html
26 #include "wtf/HashTableDeletedValueType.h"
27 #include "wtf/PassRefPtr.h"
28 #include "wtf/RawPtr.h"
34 template<typename T
> class PassRefPtr
;
36 template<typename T
> class RefPtr
{
38 ALWAYS_INLINE
RefPtr() : m_ptr(0) { }
39 ALWAYS_INLINE
RefPtr(std::nullptr_t
) : m_ptr(0) { }
40 ALWAYS_INLINE
RefPtr(T
* ptr
) : m_ptr(ptr
) { refIfNotNull(ptr
); }
41 template<typename U
> RefPtr(const RawPtr
<U
>& ptr
, EnsurePtrConvertibleArgDecl(U
, T
)) : m_ptr(ptr
.get()) { refIfNotNull(m_ptr
); }
42 ALWAYS_INLINE
explicit RefPtr(T
& ref
) : m_ptr(&ref
) { m_ptr
->ref(); }
43 ALWAYS_INLINE
RefPtr(const RefPtr
& o
) : m_ptr(o
.m_ptr
) { refIfNotNull(m_ptr
); }
44 template<typename U
> RefPtr(const RefPtr
<U
>& o
, EnsurePtrConvertibleArgDecl(U
, T
)) : m_ptr(o
.get()) { refIfNotNull(m_ptr
); }
46 RefPtr(RefPtr
&& o
) : m_ptr(o
.m_ptr
) { o
.m_ptr
= 0; }
47 RefPtr
& operator=(RefPtr
&&);
49 // See comments in PassRefPtr.h for an explanation of why this takes a const reference.
50 template<typename U
> RefPtr(const PassRefPtr
<U
>&, EnsurePtrConvertibleArgDecl(U
, T
));
52 // Hash table deleted values, which are only constructed and never copied or destroyed.
53 RefPtr(HashTableDeletedValueType
) : m_ptr(hashTableDeletedValue()) { }
54 bool isHashTableDeletedValue() const { return m_ptr
== hashTableDeletedValue(); }
56 ALWAYS_INLINE
~RefPtr() { derefIfNotNull(m_ptr
); }
58 ALWAYS_INLINE T
* get() const { return m_ptr
; }
61 PassRefPtr
<T
> release() { PassRefPtr
<T
> tmp
= adoptRef(m_ptr
); m_ptr
= 0; return tmp
; }
63 T
& operator*() const { return *m_ptr
; }
64 ALWAYS_INLINE T
* operator->() const { return m_ptr
; }
66 bool operator!() const { return !m_ptr
; }
68 // This conversion operator allows implicit conversion to bool but not to other integer types.
69 typedef T
* (RefPtr::*UnspecifiedBoolType
);
70 operator UnspecifiedBoolType() const { return m_ptr
? &RefPtr::m_ptr
: 0; }
72 RefPtr
& operator=(const RefPtr
&);
73 RefPtr
& operator=(T
*);
74 RefPtr
& operator=(const PassRefPtr
<T
>&);
75 RefPtr
& operator=(std::nullptr_t
) { clear(); return *this; }
77 template<typename U
> RefPtr
<T
>& operator=(const RefPtr
<U
>&);
78 template<typename U
> RefPtr
<T
>& operator=(const PassRefPtr
<U
>&);
79 template<typename U
> RefPtr
<T
>& operator=(const RawPtr
<U
>&);
83 static T
* hashTableDeletedValue() { return reinterpret_cast<T
*>(-1); }
89 template<typename T
> template<typename U
> inline RefPtr
<T
>::RefPtr(const PassRefPtr
<U
>& o
, EnsurePtrConvertibleArgDefn(U
, T
))
94 template<typename T
> inline void RefPtr
<T
>::clear()
101 template<typename T
> inline RefPtr
<T
>& RefPtr
<T
>::operator=(const RefPtr
& o
)
108 template<typename T
> inline RefPtr
<T
>& RefPtr
<T
>::operator=(RefPtr
&& o
)
110 // FIXME: Instead of explicitly casting to RefPtr&& here, we should use std::move, but that requires us to
111 // have a standard library that supports move semantics.
112 RefPtr ptr
= static_cast<RefPtr
&&>(o
);
117 template<typename T
> template<typename U
> inline RefPtr
<T
>& RefPtr
<T
>::operator=(const RefPtr
<U
>& o
)
124 template<typename T
> inline RefPtr
<T
>& RefPtr
<T
>::operator=(T
* optr
)
131 template<typename T
> inline RefPtr
<T
>& RefPtr
<T
>::operator=(const PassRefPtr
<T
>& o
)
138 template<typename T
> template<typename U
> inline RefPtr
<T
>& RefPtr
<T
>::operator=(const PassRefPtr
<U
>& o
)
145 template<typename T
> template<typename U
> inline RefPtr
<T
>& RefPtr
<T
>::operator=(const RawPtr
<U
>& o
)
147 RefPtr ptr
= o
.get();
152 template<class T
> inline void RefPtr
<T
>::swap(RefPtr
& o
)
154 std::swap(m_ptr
, o
.m_ptr
);
157 template<class T
> inline void swap(RefPtr
<T
>& a
, RefPtr
<T
>& b
)
162 template<typename T
, typename U
> inline bool operator==(const RefPtr
<T
>& a
, const RefPtr
<U
>& b
)
164 return a
.get() == b
.get();
167 template<typename T
, typename U
> inline bool operator==(const RefPtr
<T
>& a
, U
* b
)
172 template<typename T
, typename U
> inline bool operator==(T
* a
, const RefPtr
<U
>& b
)
177 template<typename T
, typename U
> inline bool operator!=(const RefPtr
<T
>& a
, const RefPtr
<U
>& b
)
179 return a
.get() != b
.get();
182 template<typename T
, typename U
> inline bool operator!=(const RefPtr
<T
>& a
, U
* b
)
187 template<typename T
, typename U
> inline bool operator!=(T
* a
, const RefPtr
<U
>& b
)
192 template<typename T
, typename U
> inline RefPtr
<T
> static_pointer_cast(const RefPtr
<U
>& p
)
194 return RefPtr
<T
>(static_cast<T
*>(p
.get()));
197 template<typename T
> inline T
* getPtr(const RefPtr
<T
>& p
)
202 template<typename T
> class RefPtrValuePeeker
{
204 ALWAYS_INLINE
RefPtrValuePeeker(T
* p
): m_ptr(p
) { }
205 ALWAYS_INLINE
RefPtrValuePeeker(std::nullptr_t
): m_ptr(0) { }
206 template<typename U
> RefPtrValuePeeker(const RefPtr
<U
>& p
): m_ptr(p
.get()) { }
207 template<typename U
> RefPtrValuePeeker(const PassRefPtr
<U
>& p
): m_ptr(p
.get()) { }
209 ALWAYS_INLINE
operator T
*() const { return m_ptr
; }
217 using WTF::static_pointer_cast
;
219 #endif // WTF_RefPtr_h