summaryrefslogtreecommitdiff
path: root/Source/WTF/wtf/RetainPtr.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/RetainPtr.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WTF/wtf/RetainPtr.h')
-rw-r--r--Source/WTF/wtf/RetainPtr.h487
1 files changed, 247 insertions, 240 deletions
diff --git a/Source/WTF/wtf/RetainPtr.h b/Source/WTF/wtf/RetainPtr.h
index 9cf526701..3b3f8d9bc 100644
--- a/Source/WTF/wtf/RetainPtr.h
+++ b/Source/WTF/wtf/RetainPtr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2006, 2007, 2008, 2010, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2010, 2013, 2014 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,6 +21,8 @@
#ifndef RetainPtr_h
#define RetainPtr_h
+#include <wtf/Platform.h>
+
#if USE(CF) || defined(__OBJC__)
#include <wtf/HashTraits.h>
@@ -45,288 +47,294 @@
namespace WTF {
- // Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type,
- // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work.
+// Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type,
+// so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work.
-#if !PLATFORM(IOS)
- #define AdoptCF DeprecatedAdoptCF
- #define AdoptNS DeprecatedAdoptNS
-#endif
+template<typename T> class RetainPtr;
- enum AdoptCFTag { AdoptCF };
- enum AdoptNSTag { AdoptNS };
-
-#if defined(__OBJC__) && !__has_feature(objc_arc)
-#ifdef OBJC_NO_GC
- inline void adoptNSReference(id)
- {
- }
-#else
- inline void adoptNSReference(id ptr)
- {
- if (ptr) {
- CFRetain(ptr);
- [ptr release];
- }
- }
-#endif
-#endif
+template<typename T> RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
+template<typename T> RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
- template<typename T> class RetainPtr {
- public:
- typedef typename std::remove_pointer<T>::type ValueType;
- typedef ValueType* PtrType;
- typedef CFTypeRef StorageType;
+template<typename T> class RetainPtr {
+public:
+ typedef typename std::remove_pointer<T>::type ValueType;
+ typedef ValueType* PtrType;
+ typedef CFTypeRef StorageType;
- RetainPtr() : m_ptr(0) {}
- RetainPtr(PtrType ptr) : m_ptr(toStorageType(ptr)) { if (m_ptr) CFRetain(m_ptr); }
+ RetainPtr() : m_ptr(nullptr) { }
+ RetainPtr(PtrType ptr) : m_ptr(toStorageType(ptr)) { if (m_ptr) CFRetain(m_ptr); }
- RetainPtr(AdoptCFTag, PtrType ptr)
- : m_ptr(toStorageType(ptr))
- {
-#ifdef __OBJC__
- static_assert((!std::is_convertible<T, id>::value), "Don't use adoptCF with Objective-C pointer types, use adoptNS.");
-#endif
- }
+ RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (StorageType ptr = m_ptr) CFRetain(ptr); }
-#if __has_feature(objc_arc)
- RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(toStorageType(ptr)) { if (m_ptr) CFRetain(m_ptr); }
-#else
- RetainPtr(AdoptNSTag, PtrType ptr)
- : m_ptr(toStorageType(ptr))
- {
- adoptNSReference(ptr);
- }
-#endif
-
- RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (StorageType ptr = m_ptr) CFRetain(ptr); }
+ RetainPtr(RetainPtr&& o) : m_ptr(toStorageType(o.leakRef())) { }
+ template<typename U> RetainPtr(RetainPtr<U>&& o) : m_ptr(toStorageType(o.leakRef())) { }
- RetainPtr(RetainPtr&& o) : m_ptr(toStorageType(o.leakRef())) { }
- template<typename U> RetainPtr(RetainPtr<U>&& o) : m_ptr(toStorageType(o.leakRef())) { }
+ // Hash table deleted values, which are only constructed and never copied or destroyed.
+ RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
+ bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
+
+ ~RetainPtr();
+
+ template<typename U> RetainPtr(const RetainPtr<U>&);
- // Hash table deleted values, which are only constructed and never copied or destroyed.
- RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
- bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
-
- ~RetainPtr() { if (StorageType ptr = m_ptr) CFRelease(ptr); }
-
- template<typename U> RetainPtr(const RetainPtr<U>&);
+ void clear();
+ PtrType leakRef() WARN_UNUSED_RETURN;
+ PtrType autorelease();
- void clear();
- PtrType leakRef() WARN_UNUSED_RETURN;
+ PtrType get() const { return fromStorageType(m_ptr); }
+ PtrType operator->() const { return fromStorageType(m_ptr); }
+ explicit operator PtrType() const { return fromStorageType(m_ptr); }
+ explicit operator bool() const { return m_ptr; }
- PtrType get() const { return fromStorageType(m_ptr); }
- PtrType operator->() const { return fromStorageType(m_ptr); }
- explicit operator PtrType() const { return fromStorageType(m_ptr); }
- explicit operator bool() const { return m_ptr; }
+ bool operator!() const { return !m_ptr; }
- bool operator!() const { return !m_ptr; }
-
- // This conversion operator allows implicit conversion to bool but not to other integer types.
- typedef StorageType RetainPtr::*UnspecifiedBoolType;
- operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0; }
-
- RetainPtr& operator=(const RetainPtr&);
- template<typename U> RetainPtr& operator=(const RetainPtr<U>&);
- RetainPtr& operator=(PtrType);
- template<typename U> RetainPtr& operator=(U*);
+#if !(defined (__OBJC__) && __has_feature(objc_arc))
+ // This function is useful for passing RetainPtrs to functions that return
+ // CF types as out parameters.
+ PtrType* operator&()
+ {
+ // Require that the pointer is null, to prevent leaks.
+ ASSERT(!m_ptr);
- RetainPtr& operator=(RetainPtr&&);
- template<typename U> RetainPtr& operator=(RetainPtr<U>&&);
+ return (PtrType*)&m_ptr;
+ }
+#endif
- void swap(RetainPtr&);
+ // This conversion operator allows implicit conversion to bool but not to other integer types.
+ typedef StorageType RetainPtr::*UnspecifiedBoolType;
+ operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : nullptr; }
+
+ RetainPtr& operator=(const RetainPtr&);
+ template<typename U> RetainPtr& operator=(const RetainPtr<U>&);
+ RetainPtr& operator=(PtrType);
+ template<typename U> RetainPtr& operator=(U*);
- private:
- static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1); }
+ RetainPtr& operator=(RetainPtr&&);
+ template<typename U> RetainPtr& operator=(RetainPtr<U>&&);
-#if defined (__OBJC__) && __has_feature(objc_arc)
- template<typename U>
- typename std::enable_if<std::is_convertible<U, id>::value, PtrType>::type
- fromStorageTypeHelper(StorageType ptr) const
- {
- return (__bridge PtrType)ptr;
- }
-
- template<typename U>
- typename std::enable_if<!std::is_convertible<U, id>::value, PtrType>::type
- fromStorageTypeHelper(StorageType ptr) const
- {
- return (PtrType)ptr;
- }
-
- PtrType fromStorageType(StorageType ptr) const { return fromStorageTypeHelper<PtrType>(ptr); }
- StorageType toStorageType(id ptr) const { return (__bridge StorageType)ptr; }
- StorageType toStorageType(CFTypeRef ptr) const { return (StorageType)ptr; }
-#else
- PtrType fromStorageType(StorageType ptr) const { return (PtrType)ptr; }
- StorageType toStorageType(PtrType ptr) const { return (StorageType)ptr; }
-#endif
+ void swap(RetainPtr&);
- StorageType m_ptr;
- };
+ template<typename U> friend RetainPtr<U> adoptCF(U CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
+ template<typename U> friend RetainPtr<U> adoptNS(U NS_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
- template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o)
- : m_ptr(toStorageType(o.get()))
- {
- if (StorageType ptr = m_ptr)
- CFRetain(ptr);
- }
+private:
+ enum AdoptTag { Adopt };
+ RetainPtr(PtrType ptr, AdoptTag) : m_ptr(toStorageType(ptr)) { }
- template<typename T> inline void RetainPtr<T>::clear()
- {
- if (StorageType ptr = m_ptr) {
- m_ptr = 0;
- CFRelease(ptr);
- }
- }
+ static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1); }
- template<typename T> inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef()
+#if defined (__OBJC__) && __has_feature(objc_arc)
+ template<typename U>
+ typename std::enable_if<std::is_convertible<U, id>::value, PtrType>::type
+ fromStorageTypeHelper(StorageType ptr) const
{
- PtrType ptr = fromStorageType(m_ptr);
- m_ptr = 0;
- return ptr;
+ return (__bridge PtrType)ptr;
}
- template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr& o)
+ template<typename U>
+ typename std::enable_if<!std::is_convertible<U, id>::value, PtrType>::type
+ fromStorageTypeHelper(StorageType ptr) const
{
- RetainPtr ptr = o;
- swap(ptr);
- return *this;
+ return (PtrType)ptr;
}
- template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o)
- {
- RetainPtr ptr = o;
- swap(ptr);
- return *this;
- }
+ PtrType fromStorageType(StorageType ptr) const { return fromStorageTypeHelper<PtrType>(ptr); }
+ StorageType toStorageType(id ptr) const { return (__bridge StorageType)ptr; }
+ StorageType toStorageType(CFTypeRef ptr) const { return (StorageType)ptr; }
+#else
+ PtrType fromStorageType(StorageType ptr) const { return (PtrType)ptr; }
+ StorageType toStorageType(PtrType ptr) const { return (StorageType)ptr; }
+#endif
- template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr)
- {
- RetainPtr ptr = optr;
- swap(ptr);
- return *this;
- }
+ StorageType m_ptr;
+};
- template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr)
- {
- RetainPtr ptr = optr;
- swap(ptr);
- return *this;
- }
+template<typename T> inline RetainPtr<T>::~RetainPtr()
+{
+ if (StorageType ptr = std::exchange(m_ptr, nullptr))
+ CFRelease(ptr);
+}
- template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr&& o)
- {
- RetainPtr ptr = std::move(o);
- swap(ptr);
- return *this;
- }
+// Helper function for creating a RetainPtr using template argument deduction.
+template<typename T> inline RetainPtr<T> retainPtr(T) WARN_UNUSED_RETURN;
- template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<U>&& o)
- {
- RetainPtr ptr = std::move(o);
- swap(ptr);
- return *this;
- }
+template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o)
+ : m_ptr(toStorageType(o.get()))
+{
+ if (StorageType ptr = m_ptr)
+ CFRetain(ptr);
+}
- template<typename T> inline void RetainPtr<T>::swap(RetainPtr& o)
- {
- std::swap(m_ptr, o.m_ptr);
- }
+template<typename T> inline void RetainPtr<T>::clear()
+{
+ if (StorageType ptr = std::exchange(m_ptr, nullptr))
+ CFRelease(ptr);
+}
- template<typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b)
- {
- a.swap(b);
- }
+template<typename T> inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef()
+{
+ return fromStorageType(std::exchange(m_ptr, nullptr));
+}
- template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b)
- {
- return a.get() == b.get();
- }
+#ifdef __OBJC__
+template<typename T> inline auto RetainPtr<T>::autorelease() -> PtrType
+{
+ return (__bridge PtrType)CFBridgingRelease(leakRef());
+}
+#endif
- template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, U* b)
- {
- return a.get() == b;
- }
+template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr& o)
+{
+ RetainPtr ptr = o;
+ swap(ptr);
+ return *this;
+}
+
+template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o)
+{
+ RetainPtr ptr = o;
+ swap(ptr);
+ return *this;
+}
+
+template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr)
+{
+ RetainPtr ptr = optr;
+ swap(ptr);
+ return *this;
+}
+
+template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr)
+{
+ RetainPtr ptr = optr;
+ swap(ptr);
+ return *this;
+}
+
+template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr&& o)
+{
+ RetainPtr ptr = WTFMove(o);
+ swap(ptr);
+ return *this;
+}
+
+template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<U>&& o)
+{
+ RetainPtr ptr = WTFMove(o);
+ swap(ptr);
+ return *this;
+}
+
+template<typename T> inline void RetainPtr<T>::swap(RetainPtr& o)
+{
+ std::swap(m_ptr, o.m_ptr);
+}
+
+template<typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b)
+{
+ a.swap(b);
+}
+
+template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b)
+{
+ return a.get() == b.get();
+}
+
+template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, U* b)
+{
+ return a.get() == b;
+}
+
+template<typename T, typename U> inline bool operator==(T* a, const RetainPtr<U>& b)
+{
+ return a == b.get();
+}
+
+template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b)
+{
+ return a.get() != b.get();
+}
+
+template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, U* b)
+{
+ return a.get() != b;
+}
+
+template<typename T, typename U> inline bool operator!=(T* a, const RetainPtr<U>& b)
+{
+ return a != b.get();
+}
+
+template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT ptr)
+{
+#ifdef __OBJC__
+ static_assert((!std::is_convertible<T, id>::value), "Don't use adoptCF with Objective-C pointer types, use adoptNS.");
+#endif
+ return RetainPtr<T>(ptr, RetainPtr<T>::Adopt);
+}
- template<typename T, typename U> inline bool operator==(T* a, const RetainPtr<U>& b)
- {
- return a == b.get();
- }
+#ifdef __OBJC__
+template<typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT ptr)
+{
+#if __has_feature(objc_arc)
+ return ptr;
+#elif defined(OBJC_NO_GC)
+ return RetainPtr<T>(ptr, RetainPtr<T>::Adopt);
+#else
+ RetainPtr<T> result = ptr;
+ [ptr release];
+ return result;
+#endif
+}
+#endif
- template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b)
- {
- return a.get() != b.get();
- }
+template<typename T> inline RetainPtr<T> retainPtr(T ptr)
+{
+ return ptr;
+}
- template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, U* b)
- {
- return a.get() != b;
- }
+template <typename T> struct IsSmartPtr<RetainPtr<T>> {
+ static const bool value = true;
+};
- template<typename T, typename U> inline bool operator!=(T* a, const RetainPtr<U>& b)
- {
- return a != b.get();
- }
+template<typename P> struct HashTraits<RetainPtr<P>> : SimpleClassHashTraits<RetainPtr<P>> {
+};
+
+template<typename P> struct DefaultHash<RetainPtr<P>> {
+ typedef PtrHash<RetainPtr<P>> Hash;
+};
- template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
- template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT o)
+template <typename P>
+struct RetainPtrObjectHashTraits : SimpleClassHashTraits<RetainPtr<P>> {
+ static const RetainPtr<P>& emptyValue()
{
- return RetainPtr<T>(AdoptCF, o);
+ static RetainPtr<P>& null = *(new RetainPtr<P>);
+ return null;
}
+};
- template<typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
- template<typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT o)
+template <typename P>
+struct RetainPtrObjectHash {
+ static unsigned hash(const RetainPtr<P>& o)
{
- return RetainPtr<T>(AdoptNS, o);
+ ASSERT_WITH_MESSAGE(o.get(), "attempt to use null RetainPtr in HashTable");
+ return static_cast<unsigned>(CFHash(o.get()));
}
-
- // Helper function for creating a RetainPtr using template argument deduction.
- template<typename T> inline RetainPtr<T> retainPtr(T) WARN_UNUSED_RETURN;
- template<typename T> inline RetainPtr<T> retainPtr(T o)
+ static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b)
{
- return o;
+ return CFEqual(a.get(), b.get());
}
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
- template<typename P> struct HashTraits<RetainPtr<P>> : SimpleClassHashTraits<RetainPtr<P>> { };
-
- template<typename P> struct PtrHash<RetainPtr<P>> : PtrHash<typename RetainPtr<P>::PtrType> {
- using PtrHash<typename RetainPtr<P>::PtrType>::hash;
- static unsigned hash(const RetainPtr<P>& key) { return hash(key.get()); }
- using PtrHash<typename RetainPtr<P>::PtrType>::equal;
- static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b) { return a == b; }
- static bool equal(typename RetainPtr<P>::PtrType a, const RetainPtr<P>& b) { return a == b; }
- static bool equal(const RetainPtr<P>& a, typename RetainPtr<P>::PtrType b) { return a == b; }
- };
-
- template<typename P> struct DefaultHash<RetainPtr<P>> { typedef PtrHash<RetainPtr<P>> Hash; };
-
- template <typename P>
- struct RetainPtrObjectHashTraits : SimpleClassHashTraits<RetainPtr<P>> {
- static const RetainPtr<P>& emptyValue()
- {
- static RetainPtr<P>& null = *(new RetainPtr<P>);
- return null;
- }
- };
-
- template <typename P>
- struct RetainPtrObjectHash {
- static unsigned hash(const RetainPtr<P>& o)
- {
- ASSERT_WITH_MESSAGE(o.get(), "attempt to use null RetainPtr in HashTable");
- return static_cast<unsigned>(CFHash(o.get()));
- }
- static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b)
- {
- return CFEqual(a.get(), b.get());
- }
- static const bool safeToCompareToEmptyOrDeleted = false;
- };
-
-#if !PLATFORM(IOS)
- #undef AdoptCF
- #undef AdoptNS
+#ifdef __OBJC__
+template<typename T> T* dynamic_objc_cast(id object)
+{
+ if ([object isKindOfClass:[T class]])
+ return (T *)object;
+
+ return nil;
+}
#endif
} // namespace WTF
@@ -336,9 +344,8 @@ using WTF::adoptCF;
using WTF::adoptNS;
using WTF::retainPtr;
-#if PLATFORM(IOS)
-using WTF::AdoptCF;
-using WTF::AdoptNS;
+#ifdef __OBJC__
+using WTF::dynamic_objc_cast;
#endif
#endif // USE(CF) || defined(__OBJC__)