Title: [280952] trunk/Source
Revision
280952
Author
[email protected]
Date
2021-08-11 19:08:08 -0700 (Wed, 11 Aug 2021)

Log Message

Add deduction guide to RetainPtr, use constexpr a bit more, and streamline the implementation
https://bugs.webkit.org/show_bug.cgi?id=228852

Reviewed by Sam Weinig.

Source/WebKit:

* UIProcess/mac/WKTextFinderClient.mm:
(-[WKTextFinderClient findMatchesForString:relativeToMatch:findOptions:maxResults:resultCollector:]):
Test the deduction guide by writing RetainPtr instead of RetainPtr<NSProgress>.

Source/WTF:

* wtf/RetainPtr.h: Sort includes. Made many functions constexpr including the move
constructors and adoptCF. Use using instead of typedef in most places. Use
remove_pointer_t, conditional_t, is_convertible_v, is_same_v, and other such templates
to simplify expressions. Initialize the m_ptr data member and use the default constructor.
Removed unneeded StorageType synonym for CFTypeRef. Move some inline function bodies out
of the class template definition. Use if constexpr to get rid of the need for the overloaded
autoreleaseHelper function. Added a deduction guide so we can use expressions with the
type RetainPtr on the left side, and an Objective-C pointer or CFTypeRef on the right side,
and have the appropriate RetainPtr type deduced.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (280951 => 280952)


--- trunk/Source/WTF/ChangeLog	2021-08-12 01:11:15 UTC (rev 280951)
+++ trunk/Source/WTF/ChangeLog	2021-08-12 02:08:08 UTC (rev 280952)
@@ -1,3 +1,20 @@
+2021-08-11  Darin Adler  <[email protected]>
+
+        Add deduction guide to RetainPtr, use constexpr a bit more, and streamline the implementation
+        https://bugs.webkit.org/show_bug.cgi?id=228852
+
+        Reviewed by Sam Weinig.
+
+        * wtf/RetainPtr.h: Sort includes. Made many functions constexpr including the move
+        constructors and adoptCF. Use using instead of typedef in most places. Use
+        remove_pointer_t, conditional_t, is_convertible_v, is_same_v, and other such templates
+        to simplify expressions. Initialize the m_ptr data member and use the default constructor.
+        Removed unneeded StorageType synonym for CFTypeRef. Move some inline function bodies out
+        of the class template definition. Use if constexpr to get rid of the need for the overloaded
+        autoreleaseHelper function. Added a deduction guide so we can use expressions with the
+        type RetainPtr on the left side, and an Objective-C pointer or CFTypeRef on the right side,
+        and have the appropriate RetainPtr type deduced.
+
 2021-08-11  Sihui Liu  <[email protected]>
 
         Suspend WorkQueue of ResourceLoadStatistics and LocalStorage sooner

Modified: trunk/Source/WTF/wtf/RetainPtr.h (280951 => 280952)


--- trunk/Source/WTF/wtf/RetainPtr.h	2021-08-12 01:11:15 UTC (rev 280951)
+++ trunk/Source/WTF/wtf/RetainPtr.h	2021-08-12 02:08:08 UTC (rev 280952)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2005-2019 Apple Inc. All rights reserved.
+ *  Copyright (C) 2005-2021 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
@@ -24,9 +24,10 @@
 
 #if USE(CF) || defined(__OBJC__)
 
-#include <wtf/HashTraits.h>
 #include <algorithm>
 #include <cstddef>
+#include <wtf/HashTraits.h>
+#include <wtf/NeverDestroyed.h>
 
 #if USE(CF)
 #include <CoreFoundation/CoreFoundation.h>
@@ -65,7 +66,8 @@
 
 template<typename T> class RetainPtr;
 
-template<typename T> RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
+template<typename T> constexpr RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
+
 #ifdef __OBJC__
 template<typename T> RetainPtr<typename RetainPtr<T>::HelperPtrType> adoptNS(T NS_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
 #endif
@@ -72,50 +74,50 @@
 
 template<typename T> class RetainPtr {
 public:
-    typedef typename std::remove_pointer<T>::type ValueType;
-    typedef ValueType* PtrType;
-    typedef CFTypeRef StorageType;
+    using ValueType = std::remove_pointer_t<T>;
+    using PtrType = ValueType*;
 
 #ifdef __OBJC__
-    typedef typename std::conditional<std::is_convertible<T, id>::value && !std::is_same<T, id>::value, typename std::remove_pointer<T>::type, T>::type HelperPtrType;
+    using HelperPtrType = typename std::conditional_t<std::is_convertible_v<T, id> && !std::is_same_v<T, id>, std::remove_pointer_t<T>, T>;
 #else
-    typedef T HelperPtrType;
+    using HelperPtrType = PtrType;
 #endif
 
-    RetainPtr() : m_ptr(nullptr) { }
-    RetainPtr(PtrType ptr) : m_ptr(toStorageType(ptr)) { if (m_ptr) CFRetain(m_ptr); }
+    RetainPtr() = default;
+    RetainPtr(PtrType);
 
-    RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (StorageType ptr = m_ptr) CFRetain(ptr); }
+    RetainPtr(const RetainPtr&);
+    template<typename U> RetainPtr(const RetainPtr<U>&);
 
-    RetainPtr(RetainPtr&& o) : m_ptr(toStorageType(o.leakRef())) { }
-    template<typename U> RetainPtr(RetainPtr<U>&& o) : m_ptr(toStorageType(o.leakRef())) { }
+    constexpr RetainPtr(RetainPtr&& o) : m_ptr(toStorageType(o.leakRef())) { }
+    template<typename U> constexpr 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(); }
-    
+    constexpr RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
+    constexpr bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
+
     ~RetainPtr();
-    
-    template<typename U> RetainPtr(const RetainPtr<U>&);
 
     void clear();
     PtrType leakRef() WARN_UNUSED_RETURN;
     PtrType autorelease();
+
 #ifdef __OBJC__
     id bridgingAutorelease();
 #endif
 
-    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; }
+    constexpr PtrType get() const { return fromStorageType(m_ptr); }
+    constexpr PtrType operator->() const { return fromStorageType(m_ptr); }
+    constexpr explicit operator PtrType() const { return fromStorageType(m_ptr); }
+    constexpr explicit operator bool() const { return m_ptr; }
 
-    bool operator!() const { return !m_ptr; }
+    constexpr bool operator!() const { return !m_ptr; }
 
     // This conversion operator allows implicit conversion to bool but not to other integer types.
-    typedef StorageType RetainPtr::*UnspecifiedBoolType;
+    // FIXME: Eventually we should remove this; it's an outdated technique and less needed since we have explicit operator bool.
+    typedef CFTypeRef 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);
@@ -126,7 +128,8 @@
 
     void swap(RetainPtr&);
 
-    template<typename U> friend RetainPtr<U> adoptCF(U CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
+    template<typename U> friend constexpr RetainPtr<U> adoptCF(U CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
+
 #ifdef __OBJC__
     template<typename U> friend RetainPtr<typename RetainPtr<U>::HelperPtrType> adoptNS(U NS_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
 #endif
@@ -133,63 +136,64 @@
 
 private:
     enum AdoptTag { Adopt };
-    RetainPtr(PtrType ptr, AdoptTag) : m_ptr(toStorageType(ptr)) { }
+    constexpr RetainPtr(PtrType ptr, AdoptTag) : m_ptr(toStorageType(ptr)) { }
 
-    static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1); }
+    static constexpr PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1); }
 
 #ifdef __OBJC__
-    template<typename U>
-    typename std::enable_if<std::is_convertible<U, id>::value, PtrType>::type
-    fromStorageTypeHelper(StorageType ptr) const
+    template<typename U> constexpr std::enable_if_t<std::is_convertible_v<U, id>, PtrType> fromStorageTypeHelper(CFTypeRef ptr) const
     {
         return (__bridge PtrType)const_cast<CF_BRIDGED_TYPE(id) void*>(ptr);
     }
-
-    template<typename U>
-    typename std::enable_if<!std::is_convertible<U, id>::value, PtrType>::type
-    fromStorageTypeHelper(StorageType ptr) const
+    template<typename U> constexpr std::enable_if_t<!std::is_convertible_v<U, id>, PtrType> fromStorageTypeHelper(CFTypeRef ptr) const
     {
         return (PtrType)const_cast<CF_BRIDGED_TYPE(id) void*>(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; }
+    constexpr PtrType fromStorageType(CFTypeRef ptr) const { return fromStorageTypeHelper<PtrType>(ptr); }
+    constexpr CFTypeRef toStorageType(id ptr) const { return (__bridge CFTypeRef)ptr; }
+    constexpr CFTypeRef toStorageType(CFTypeRef ptr) const { return (CFTypeRef)ptr; }
 #else
-    PtrType fromStorageType(StorageType ptr) const
+    constexpr PtrType fromStorageType(CFTypeRef ptr) const
     {
         return (PtrType)const_cast<CF_BRIDGED_TYPE(id) void*>(ptr);
     }
-    StorageType toStorageType(PtrType ptr) const { return (StorageType)ptr; }
+    constexpr CFTypeRef toStorageType(PtrType ptr) const { return (CFTypeRef)ptr; }
 #endif
 
-#ifdef __OBJC__
-    template<typename U> std::enable_if_t<std::is_convertible<U, id>::value, PtrType> autoreleaseHelper();
-    template<typename U> std::enable_if_t<!std::is_convertible<U, id>::value, PtrType> autoreleaseHelper();
-#endif
-
-    StorageType m_ptr;
+    CFTypeRef m_ptr { nullptr };
 };
 
+template<typename T> RetainPtr(T) -> RetainPtr<std::remove_pointer_t<T>>;
+
 // Helper function for creating a RetainPtr using template argument deduction.
 template<typename T> RetainPtr<typename RetainPtr<T>::HelperPtrType> retainPtr(T) WARN_UNUSED_RETURN;
 
 template<typename T> inline RetainPtr<T>::~RetainPtr()
 {
-    if (StorageType ptr = std::exchange(m_ptr, nullptr))
+    if (auto ptr = std::exchange(m_ptr, nullptr))
         CFRelease(ptr);
 }
 
+template<typename T> inline RetainPtr<T>::RetainPtr(PtrType ptr)
+    : m_ptr(toStorageType(ptr))
+{
+    if (m_ptr)
+        CFRetain(m_ptr);
+}
+
+template<typename T> inline RetainPtr<T>::RetainPtr(const RetainPtr& o)
+    : RetainPtr(o.get())
+{
+}
+
 template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o)
-    : m_ptr(toStorageType(o.get()))
+    : RetainPtr(o.get())
 {
-    if (StorageType ptr = m_ptr)
-        CFRetain(ptr);
 }
 
 template<typename T> inline void RetainPtr<T>::clear()
 {
-    if (StorageType ptr = std::exchange(m_ptr, nullptr))
+    if (auto ptr = std::exchange(m_ptr, nullptr))
         CFRelease(ptr);
 }
 
@@ -198,35 +202,20 @@
     return fromStorageType(std::exchange(m_ptr, nullptr));
 }
 
-#ifndef __OBJC__
-
 template<typename T> inline auto RetainPtr<T>::autorelease() -> PtrType
 {
+#ifdef __OBJC__
+    if constexpr (std::is_convertible_v<PtrType, id>)
+        return CFBridgingRelease(std::exchange(m_ptr, nullptr));
+#endif
     if (m_ptr)
         CFAutorelease(m_ptr);
     return leakRef();
 }
 
-#else
+#ifdef __OBJC__
 
-template<typename T> template<typename U> inline auto RetainPtr<T>::autoreleaseHelper() -> std::enable_if_t<std::is_convertible<U, id>::value, PtrType>
-{
-    return CFBridgingRelease(std::exchange(m_ptr, nullptr));
-}
-
-template<typename T> template<typename U> inline auto RetainPtr<T>::autoreleaseHelper() -> std::enable_if_t<!std::is_convertible<U, id>::value, PtrType>
-{
-    if (m_ptr)
-        CFAutorelease(m_ptr);
-    return leakRef();
-}
-
-template<typename T> inline auto RetainPtr<T>::autorelease() -> PtrType
-{
-    return autoreleaseHelper<PtrType>();
-}
-
-// FIXME: It would be nice if we could base the return type on the type that is toll-free bridged with T rather than using id.
+// FIXME: It would be better if we could base the return type on the type that is toll-free bridged with T rather than using id.
 template<typename T> inline id RetainPtr<T>::bridgingAutorelease()
 {
     static_assert((!std::is_convertible<PtrType, id>::value), "Don't use bridgingAutorelease for Objective-C pointer types.");
@@ -287,37 +276,37 @@
     a.swap(b);
 }
 
-template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b)
+template<typename T, typename U> constexpr 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)
+template<typename T, typename U> constexpr 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) 
+template<typename T, typename U> constexpr 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)
+template<typename T, typename U> constexpr 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)
+template<typename T, typename U> constexpr 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)
+template<typename T, typename U> constexpr bool operator!=(T* a, const RetainPtr<U>& b)
 { 
     return a != b.get(); 
 }
 
-template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT ptr)
+template<typename T> constexpr 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.");
@@ -331,7 +320,8 @@
 #if __has_feature(objc_arc)
     return ptr;
 #elif defined(OBJC_NO_GC)
-    return RetainPtr<typename RetainPtr<T>::HelperPtrType>(ptr, RetainPtr<typename RetainPtr<T>::HelperPtrType>::Adopt);
+    using ReturnType = RetainPtr<typename RetainPtr<T>::HelperPtrType>;
+    return ReturnType { ptr, ReturnType::Adopt };
 #else
     RetainPtr<typename RetainPtr<T>::HelperPtrType> result = ptr;
     [ptr release];
@@ -345,7 +335,7 @@
     return ptr;
 }
 
-template <typename T> struct IsSmartPtr<RetainPtr<T>> {
+template<typename T> struct IsSmartPtr<RetainPtr<T>> {
     static constexpr bool value = true;
 };
 
@@ -354,17 +344,15 @@
 
 template<typename P> struct DefaultHash<RetainPtr<P>> : PtrHash<RetainPtr<P>> { };
 
-template <typename P>
-struct RetainPtrObjectHashTraits : SimpleClassHashTraits<RetainPtr<P>> {
+template<typename P> struct RetainPtrObjectHashTraits : SimpleClassHashTraits<RetainPtr<P>> {
     static const RetainPtr<P>& emptyValue()
     {
-        static RetainPtr<P>& null = *(new RetainPtr<P>);
+        static NeverDestroyed<RetainPtr<P>> null;
         return null;
     }
 };
 
-template <typename P>
-struct RetainPtrObjectHash {
+template<typename P> struct RetainPtrObjectHash {
     static unsigned hash(const RetainPtr<P>& o)
     {
         ASSERT_WITH_MESSAGE(o.get(), "attempt to use null RetainPtr in HashTable");

Modified: trunk/Source/WebKit/ChangeLog (280951 => 280952)


--- trunk/Source/WebKit/ChangeLog	2021-08-12 01:11:15 UTC (rev 280951)
+++ trunk/Source/WebKit/ChangeLog	2021-08-12 02:08:08 UTC (rev 280952)
@@ -1,3 +1,14 @@
+2021-08-11  Darin Adler  <[email protected]>
+
+        Add deduction guide to RetainPtr, use constexpr a bit more, and streamline the implementation
+        https://bugs.webkit.org/show_bug.cgi?id=228852
+
+        Reviewed by Sam Weinig.
+
+        * UIProcess/mac/WKTextFinderClient.mm:
+        (-[WKTextFinderClient findMatchesForString:relativeToMatch:findOptions:maxResults:resultCollector:]):
+        Test the deduction guide by writing RetainPtr instead of RetainPtr<NSProgress>.
+
 2021-08-11  Peng Liu  <[email protected]>
 
         [ BigSur Debug ] TestWebKitAPI.GPUProcess.CrashWhilePlayingAudioViaCreateMediaElementSource is flaky, hitting ASSERTION FAILED: !isInRoutingArbitrationForToken(token)

Modified: trunk/Source/WebKit/UIProcess/mac/WKTextFinderClient.mm (280951 => 280952)


--- trunk/Source/WebKit/UIProcess/mac/WKTextFinderClient.mm	2021-08-12 01:11:15 UTC (rev 280951)
+++ trunk/Source/WebKit/UIProcess/mac/WKTextFinderClient.mm	2021-08-12 02:08:08 UTC (rev 280952)
@@ -225,7 +225,7 @@
         kitFindOptions.add(WebKit::FindOptions::DetermineMatchIndex);
     }
 
-    RetainPtr<NSProgress> progress = [NSProgress progressWithTotalUnitCount:1];
+    RetainPtr progress = [NSProgress progressWithTotalUnitCount:1];
     auto copiedResultCollector = Block_copy(resultCollector);
     _findReplyCallbacks.append([progress, copiedResultCollector] (NSArray *matches, bool didWrap) {
         [progress setCompletedUnitCount:1];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to