diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/RetainPtr.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WTF/wtf/RetainPtr.h')
-rw-r--r-- | Source/WTF/wtf/RetainPtr.h | 487 |
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__) |