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 "HashTraits.h"
26 #include "TypeTraits.h"
30 #include <CoreFoundation/CoreFoundation.h>
34 #import <Foundation/Foundation.h>
39 // Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type,
40 // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work.
42 enum AdoptCFTag
{ AdoptCF
};
43 enum AdoptNSTag
{ AdoptNS
};
46 inline void adoptNSReference(id ptr
)
55 template<typename T
> class RetainPtr
{
57 typedef typename RemovePointer
<T
>::Type ValueType
;
58 typedef ValueType
* PtrType
;
60 RetainPtr() : m_ptr(0) {}
61 RetainPtr(PtrType ptr
) : m_ptr(ptr
) { if (ptr
) CFRetain(ptr
); }
63 RetainPtr(AdoptCFTag
, PtrType ptr
) : m_ptr(ptr
) { }
64 RetainPtr(AdoptNSTag
, PtrType ptr
) : m_ptr(ptr
) { adoptNSReference(ptr
); }
66 RetainPtr(const RetainPtr
& o
) : m_ptr(o
.m_ptr
) { if (PtrType ptr
= m_ptr
) CFRetain(ptr
); }
68 // Hash table deleted values, which are only constructed and never copied or destroyed.
69 RetainPtr(HashTableDeletedValueType
) : m_ptr(hashTableDeletedValue()) { }
70 bool isHashTableDeletedValue() const { return m_ptr
== hashTableDeletedValue(); }
72 ~RetainPtr() { if (PtrType ptr
= m_ptr
) CFRelease(ptr
); }
74 template<typename U
> RetainPtr(const RetainPtr
<U
>&);
76 PtrType
get() const { return m_ptr
; }
79 PtrType
leakRef() WARN_UNUSED_RETURN
;
81 PtrType
operator->() const { return m_ptr
; }
83 bool operator!() const { return !m_ptr
; }
85 // This conversion operator allows implicit conversion to bool but not to other integer types.
86 typedef PtrType
RetainPtr::*UnspecifiedBoolType
;
87 operator UnspecifiedBoolType() const { return m_ptr
? &RetainPtr::m_ptr
: 0; }
89 RetainPtr
& operator=(const RetainPtr
&);
90 template<typename U
> RetainPtr
& operator=(const RetainPtr
<U
>&);
91 RetainPtr
& operator=(PtrType
);
92 template<typename U
> RetainPtr
& operator=(U
*);
94 RetainPtr
& operator=(std::nullptr_t
) { clear(); return *this; }
97 void adoptCF(PtrType
);
98 void adoptNS(PtrType
);
100 void swap(RetainPtr
&);
102 // FIXME: Remove releaseRef once we change all callers to call leakRef instead.
103 PtrType
releaseRef() { return leakRef(); }
106 static T
* hashTableDeletedValue() { return reinterpret_cast<T
*>(-1); }
111 template<typename T
> template<typename U
> inline RetainPtr
<T
>::RetainPtr(const RetainPtr
<U
>& o
)
114 if (PtrType ptr
= m_ptr
)
118 template<typename T
> inline void RetainPtr
<T
>::clear()
120 if (PtrType ptr
= m_ptr
) {
126 template<typename T
> inline typename RetainPtr
<T
>::PtrType RetainPtr
<T
>::leakRef()
133 template<typename T
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(const RetainPtr
<T
>& o
)
135 PtrType optr
= o
.get();
145 template<typename T
> template<typename U
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(const RetainPtr
<U
>& o
)
147 PtrType optr
= o
.get();
157 template<typename T
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(PtrType optr
)
168 template<typename T
> inline void RetainPtr
<T
>::adoptCF(PtrType optr
)
176 template<typename T
> inline void RetainPtr
<T
>::adoptNS(PtrType optr
)
178 adoptNSReference(optr
);
186 template<typename T
> template<typename U
> inline RetainPtr
<T
>& RetainPtr
<T
>::operator=(U
* optr
)
197 template<typename T
> inline void RetainPtr
<T
>::swap(RetainPtr
<T
>& o
)
199 std::swap(m_ptr
, o
.m_ptr
);
202 template<typename T
> inline void swap(RetainPtr
<T
>& a
, RetainPtr
<T
>& b
)
207 template<typename T
, typename U
> inline bool operator==(const RetainPtr
<T
>& a
, const RetainPtr
<U
>& b
)
209 return a
.get() == b
.get();
212 template<typename T
, typename U
> inline bool operator==(const RetainPtr
<T
>& a
, U
* b
)
217 template<typename T
, typename U
> inline bool operator==(T
* a
, const RetainPtr
<U
>& b
)
222 template<typename T
, typename U
> inline bool operator!=(const RetainPtr
<T
>& a
, const RetainPtr
<U
>& b
)
224 return a
.get() != b
.get();
227 template<typename T
, typename U
> inline bool operator!=(const RetainPtr
<T
>& a
, U
* b
)
232 template<typename T
, typename U
> inline bool operator!=(T
* a
, const RetainPtr
<U
>& b
)
237 template<typename P
> struct HashTraits
<RetainPtr
<P
> > : SimpleClassHashTraits
<RetainPtr
<P
> > { };
239 template<typename P
> struct PtrHash
<RetainPtr
<P
> > : PtrHash
<P
*> {
240 using PtrHash
<P
*>::hash
;
241 static unsigned hash(const RetainPtr
<P
>& key
) { return hash(key
.get()); }
242 using PtrHash
<P
*>::equal
;
243 static bool equal(const RetainPtr
<P
>& a
, const RetainPtr
<P
>& b
) { return a
== b
; }
244 static bool equal(P
* a
, const RetainPtr
<P
>& b
) { return a
== b
; }
245 static bool equal(const RetainPtr
<P
>& a
, P
* b
) { return a
== b
; }
248 template<typename P
> struct DefaultHash
<RetainPtr
<P
> > { typedef PtrHash
<RetainPtr
<P
> > Hash
; };
254 using WTF::RetainPtr
;
256 #endif // WTF_RetainPtr_h