Przeglądaj źródła

AK+Kernel: Use requires expression when invoking ref counting hooks

Replace some old-school template trickery with C++20 requires. :^)
Andreas Kling 3 lat temu
rodzic
commit
c4a0f01b02

+ 6 - 28
AK/RefCounted.h

@@ -18,32 +18,6 @@
 
 namespace AK {
 
-template<class T>
-constexpr auto call_will_be_destroyed_if_present(const T* object) -> decltype(const_cast<T*>(object)->will_be_destroyed(), TrueType {})
-{
-    const_cast<T*>(object)->will_be_destroyed();
-    return {};
-}
-
-// NOLINTNEXTLINE(cert-dcl50-cpp) variadic argument used to implement "is detected" pattern
-constexpr auto call_will_be_destroyed_if_present(...) -> FalseType
-{
-    return {};
-}
-
-template<class T>
-constexpr auto call_one_ref_left_if_present(const T* object) -> decltype(const_cast<T*>(object)->one_ref_left(), TrueType {})
-{
-    const_cast<T*>(object)->one_ref_left();
-    return {};
-}
-
-// NOLINTNEXTLINE(cert-dcl50-cpp) variadic argument used to implement "is detected" pattern
-constexpr auto call_one_ref_left_if_present(...) -> FalseType
-{
-    return {};
-}
-
 class RefCountedBase {
     AK_MAKE_NONCOPYABLE(RefCountedBase);
     AK_MAKE_NONMOVABLE(RefCountedBase);
@@ -87,13 +61,17 @@ class RefCounted : public RefCountedBase {
 public:
     bool unref() const
     {
+        auto const* that = static_cast<T const*>(this);
+
         auto new_ref_count = deref_base();
         if (new_ref_count == 0) {
-            call_will_be_destroyed_if_present(static_cast<const T*>(this));
+            if constexpr (requires { that->will_be_destroyed(); })
+                that->will_be_destroyed();
             delete static_cast<const T*>(this);
             return true;
         } else if (new_ref_count == 1) {
-            call_one_ref_left_if_present(static_cast<const T*>(this));
+            if constexpr (requires { that->one_ref_left(); })
+                that->one_ref_left();
         }
         return false;
     }

+ 8 - 4
Kernel/Library/ListedRefCounted.h

@@ -25,10 +25,12 @@ class ListedRefCounted : public RefCountedBase {
 public:
     bool unref() const
     {
+        auto const* that = static_cast<T const*>(this);
+
         auto callback = [&](auto& list) {
             auto new_ref_count = deref_base();
             if (new_ref_count == 0)
-                list.remove(const_cast<T&>(static_cast<T const&>(*this)));
+                list.remove(const_cast<T&>(*that));
             return new_ref_count;
         };
 
@@ -38,10 +40,12 @@ public:
         else if constexpr (Lock == LockType::Mutex)
             new_ref_count = T::all_instances().with_exclusive(callback);
         if (new_ref_count == 0) {
-            call_will_be_destroyed_if_present(static_cast<const T*>(this));
-            delete const_cast<T*>(static_cast<T const*>(this));
+            if constexpr (requires { that->will_be_destroyed(); })
+                that->will_be_destroyed();
+            delete that;
         } else if (new_ref_count == 1) {
-            call_one_ref_left_if_present(static_cast<T const*>(this));
+            if constexpr (requires { that->one_ref_left(); })
+                that->one_ref_left();
         }
         return new_ref_count == 0;
     }

+ 8 - 30
Kernel/Library/ThreadSafeRefCounted.h

@@ -15,32 +15,6 @@
 
 namespace AK {
 
-template<class T>
-constexpr auto call_will_be_destroyed_if_present(const T* object) -> decltype(const_cast<T*>(object)->will_be_destroyed(), TrueType {})
-{
-    const_cast<T*>(object)->will_be_destroyed();
-    return {};
-}
-
-// NOLINTNEXTLINE(cert-dcl50-cpp) variadic argument used to implement "is detected" pattern
-constexpr auto call_will_be_destroyed_if_present(...) -> FalseType
-{
-    return {};
-}
-
-template<class T>
-constexpr auto call_one_ref_left_if_present(const T* object) -> decltype(const_cast<T*>(object)->one_ref_left(), TrueType {})
-{
-    const_cast<T*>(object)->one_ref_left();
-    return {};
-}
-
-// NOLINTNEXTLINE(cert-dcl50-cpp) variadic argument used to implement "is detected" pattern
-constexpr auto call_one_ref_left_if_present(...) -> FalseType
-{
-    return {};
-}
-
 class RefCountedBase {
     AK_MAKE_NONCOPYABLE(RefCountedBase);
     AK_MAKE_NONMOVABLE(RefCountedBase);
@@ -95,14 +69,18 @@ class RefCounted : public RefCountedBase {
 public:
     bool unref() const
     {
+        auto const* that = static_cast<T const*>(this);
         auto new_ref_count = deref_base();
         if (new_ref_count == 0) {
-            call_will_be_destroyed_if_present(static_cast<const T*>(this));
-            delete static_cast<const T*>(this);
+            if constexpr (requires { that->will_be_destroyed(); })
+                that->will_be_destroyed();
+            delete that;
             return true;
         }
-        if (new_ref_count == 1)
-            call_one_ref_left_if_present(static_cast<const T*>(this));
+        if (new_ref_count == 1) {
+            if constexpr (requires { that->one_ref_left(); })
+                that->one_ref_left();
+        }
         return false;
     }
 };