From c4a0f01b02d84117e644f2aff4396bdac1bcf40d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 8 Jan 2022 15:15:55 +0100 Subject: [PATCH] AK+Kernel: Use requires expression when invoking ref counting hooks Replace some old-school template trickery with C++20 requires. :^) --- AK/RefCounted.h | 34 +++++------------------- Kernel/Library/ListedRefCounted.h | 12 ++++++--- Kernel/Library/ThreadSafeRefCounted.h | 38 ++++++--------------------- 3 files changed, 22 insertions(+), 62 deletions(-) diff --git a/AK/RefCounted.h b/AK/RefCounted.h index 5d98811b0c4..7b450703424 100644 --- a/AK/RefCounted.h +++ b/AK/RefCounted.h @@ -18,32 +18,6 @@ namespace AK { -template -constexpr auto call_will_be_destroyed_if_present(const T* object) -> decltype(const_cast(object)->will_be_destroyed(), TrueType {}) -{ - const_cast(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 -constexpr auto call_one_ref_left_if_present(const T* object) -> decltype(const_cast(object)->one_ref_left(), TrueType {}) -{ - const_cast(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(this); + auto new_ref_count = deref_base(); if (new_ref_count == 0) { - call_will_be_destroyed_if_present(static_cast(this)); + if constexpr (requires { that->will_be_destroyed(); }) + that->will_be_destroyed(); delete static_cast(this); return true; } else if (new_ref_count == 1) { - call_one_ref_left_if_present(static_cast(this)); + if constexpr (requires { that->one_ref_left(); }) + that->one_ref_left(); } return false; } diff --git a/Kernel/Library/ListedRefCounted.h b/Kernel/Library/ListedRefCounted.h index 0f84b905d20..2dd8f470393 100644 --- a/Kernel/Library/ListedRefCounted.h +++ b/Kernel/Library/ListedRefCounted.h @@ -25,10 +25,12 @@ class ListedRefCounted : public RefCountedBase { public: bool unref() const { + auto const* that = static_cast(this); + auto callback = [&](auto& list) { auto new_ref_count = deref_base(); if (new_ref_count == 0) - list.remove(const_cast(static_cast(*this))); + list.remove(const_cast(*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(this)); - delete const_cast(static_cast(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(this)); + if constexpr (requires { that->one_ref_left(); }) + that->one_ref_left(); } return new_ref_count == 0; } diff --git a/Kernel/Library/ThreadSafeRefCounted.h b/Kernel/Library/ThreadSafeRefCounted.h index cc7e1caf35d..569ecbc8317 100644 --- a/Kernel/Library/ThreadSafeRefCounted.h +++ b/Kernel/Library/ThreadSafeRefCounted.h @@ -15,32 +15,6 @@ namespace AK { -template -constexpr auto call_will_be_destroyed_if_present(const T* object) -> decltype(const_cast(object)->will_be_destroyed(), TrueType {}) -{ - const_cast(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 -constexpr auto call_one_ref_left_if_present(const T* object) -> decltype(const_cast(object)->one_ref_left(), TrueType {}) -{ - const_cast(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(this); auto new_ref_count = deref_base(); if (new_ref_count == 0) { - call_will_be_destroyed_if_present(static_cast(this)); - delete static_cast(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(this)); + if (new_ref_count == 1) { + if constexpr (requires { that->one_ref_left(); }) + that->one_ref_left(); + } return false; } };