2 * Copyright (C) 2005, 2006, 2007, 2008, 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.
24 #include "wtf/HashTableDeletedValueType.h"
25 #include "wtf/HashTraits.h"
26 #include "wtf/NullPtr.h"
27 #include "wtf/TypeTraits.h"
32 #include <CoreFoundation/CoreFoundation.h>
36 #import <Foundation/Foundation.h>
39 #ifndef CF_RELEASES_ARGUMENT
40 #define CF_RELEASES_ARGUMENT
43 #ifndef NS_RELEASES_ARGUMENT
44 #define NS_RELEASES_ARGUMENT
49 // Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type,
50 // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work.
52 enum AdoptCFTag
{ AdoptCF
};
53 enum AdoptNSTag
{ AdoptNS
};
56 inline void adoptNSReference(id ptr
)
65 template<typename T
> class RetainPtr
{
67 typedef typename RemovePointer
<T
>::Type ValueType
;
68 typedef ValueType
* PtrType
;
70 RetainPtr() : m_ptr(0) {}
71 RetainPtr(PtrType ptr
) : m_ptr(ptr
) { if (ptr
) CFRetain(ptr
); }
73 RetainPtr(AdoptCFTag
, PtrType ptr
) : m_ptr(ptr
) { }
74 RetainPtr(AdoptNSTag
, PtrType ptr
) : m_ptr(ptr
) { adoptNSReference(ptr
); }
76 RetainPtr(const RetainPtr
& o
) : m_ptr(o
.m_ptr
) { if (PtrType ptr
= m_ptr
) CFRetain(ptr
); }
78 RetainPtr(RetainPtr
&& o
) : m_ptr(o
.leakRef()) { }
80 // Hash table deleted values, which are only constructed and never copied or destroyed.
81 RetainPtr(HashTableDeletedValueType
) : m_ptr(hashTableDeletedValue()) { }
82 bool isHashTableDeletedValue() const { return m_ptr
== hashTableDeletedValue(); }
84 ~RetainPtr() { if (PtrType ptr
= m_ptr
) CFRelease(ptr
); }
86 template<typename U
> RetainPtr(const RetainPtr
<U
>&);
89 PtrType
leakRef() WARN_UNUSED_RETURN
;
91 PtrType
get() const { return m_ptr
; }
92 PtrType
operator->() const { return m_ptr
; }
93 #if COMPILER_SUPPORTS(CXX_EXPLICIT_CONVERSIONS)
94 explicit operator PtrType() const { return m_ptr
; }
97 bool operator!() const { return !m_ptr
; }
99 // This conversion operator allows implicit conversion to bool but not to other integer types.
100 typedef PtrType
RetainPtr::*UnspecifiedBoolType
;
101 operator UnspecifiedBoolType() const { return m_ptr
? &RetainPtr::m_ptr
: 0; }
103 RetainPtr
& operator=(const RetainPtr
&);
104 template<typename U
> RetainPtr
& operator=(const RetainPtr
<U
>&);
105 RetainPtr
& operator=(PtrType
);
106 template<typename U
> RetainPtr
& operator=(U
*);
108 RetainPtr
& operator=(RetainPtr
&&);
109 template<typename U
> RetainPtr
& operator=(RetainPtr
<U
>&&);
111 #if !COMPILER_SUPPORTS(CXX_NULLPTR)
112 RetainPtr
& operator=(std::nullptr_t
) { clear(); return *this; }
115 void adoptCF(PtrType
);
116 void adoptNS(PtrType
);
118 void swap(RetainPtr
&);
121 static PtrType
hashTableDeletedValue() { return reinterpret_cast<PtrType
>(-1); }
126 template<typename T
> template<typename U
> inline RetainPtr
<T
>::RetainPtr(const RetainPtr
<U
>& o
)
129 if (PtrType ptr
= m_ptr
)
133 template<typename T
> inline void RetainPtr
<T
>::clear()
135 if (PtrType ptr
= m_ptr
) {
141 template<typename T
> inline typename RetainPtr
<T
>::PtrType RetainPtr
<T
>::leakRef()
148 template<typename T
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(const RetainPtr
<T
>& o
)
150 PtrType optr
= o
.get();
160 template<typename T
> template<typename U
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(const RetainPtr
<U
>& o
)
162 PtrType optr
= o
.get();
172 template<typename T
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(PtrType optr
)
183 template<typename T
> template<typename U
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(U
* optr
)
194 template<typename T
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(RetainPtr
<T
>&& o
)
196 adoptCF(o
.leakRef());
200 template<typename T
> template<typename U
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(RetainPtr
<U
>&& o
)
202 adoptCF(o
.leakRef());
206 template<typename T
> inline void RetainPtr
<T
>::adoptCF(PtrType optr
)
214 template<typename T
> inline void RetainPtr
<T
>::adoptNS(PtrType optr
)
216 adoptNSReference(optr
);
224 template<typename T
> inline void RetainPtr
<T
>::swap(RetainPtr
<T
>& o
)
226 std::swap(m_ptr
, o
.m_ptr
);
229 template<typename T
> inline void swap(RetainPtr
<T
>& a
, RetainPtr
<T
>& b
)
234 template<typename T
, typename U
> inline bool operator==(const RetainPtr
<T
>& a
, const RetainPtr
<U
>& b
)
236 return a
.get() == b
.get();
239 template<typename T
, typename U
> inline bool operator==(const RetainPtr
<T
>& a
, U
* b
)
244 template<typename T
, typename U
> inline bool operator==(T
* a
, const RetainPtr
<U
>& b
)
249 template<typename T
, typename U
> inline bool operator!=(const RetainPtr
<T
>& a
, const RetainPtr
<U
>& b
)
251 return a
.get() != b
.get();
254 template<typename T
, typename U
> inline bool operator!=(const RetainPtr
<T
>& a
, U
* b
)
259 template<typename T
, typename U
> inline bool operator!=(T
* a
, const RetainPtr
<U
>& b
)
264 template<typename T
> inline RetainPtr
<T
> adoptCF(T CF_RELEASES_ARGUMENT
) WARN_UNUSED_RETURN
;
265 template<typename T
> inline RetainPtr
<T
> adoptCF(T o
)
267 return RetainPtr
<T
>(AdoptCF
, o
);
270 template<typename T
> inline RetainPtr
<T
> adoptNS(T NS_RELEASES_ARGUMENT
) WARN_UNUSED_RETURN
;
271 template<typename T
> inline RetainPtr
<T
> adoptNS(T o
)
273 return RetainPtr
<T
>(AdoptNS
, o
);
276 // Helper function for creating a RetainPtr using template argument deduction.
277 template<typename T
> inline RetainPtr
<T
> retainPtr(T
) WARN_UNUSED_RETURN
;
278 template<typename T
> inline RetainPtr
<T
> retainPtr(T o
)
280 return RetainPtr
<T
>(o
);
283 template<typename P
> struct HashTraits
<RetainPtr
<P
>> : SimpleClassHashTraits
<RetainPtr
<P
>> { };
285 template<typename P
> struct PtrHash
<RetainPtr
<P
>> : PtrHash
<typename RetainPtr
<P
>::PtrType
> {
286 using PtrHash
<typename RetainPtr
<P
>::PtrType
>::hash
;
287 static unsigned hash(const RetainPtr
<P
>& key
) { return hash(key
.get()); }
288 using PtrHash
<typename RetainPtr
<P
>::PtrType
>::equal
;
289 static bool equal(const RetainPtr
<P
>& a
, const RetainPtr
<P
>& b
) { return a
== b
; }
290 static bool equal(typename RetainPtr
<P
>::PtrType a
, const RetainPtr
<P
>& b
) { return a
== b
; }
291 static bool equal(const RetainPtr
<P
>& a
, typename RetainPtr
<P
>::PtrType b
) { return a
== b
; }
294 template<typename P
> struct DefaultHash
<RetainPtr
<P
>> { typedef PtrHash
<RetainPtr
<P
>> Hash
; };
301 using WTF::RetainPtr
;
302 using WTF::retainPtr
;
304 #endif // WTF_RetainPtr_h