mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
AK+Kernel: Use requires expression when invoking ref counting hooks
Replace some old-school template trickery with C++20 requires. :^)
This commit is contained in:
parent
ec74afdb8d
commit
c4a0f01b02
Notes:
sideshowbarker
2024-07-17 21:25:50 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c4a0f01b02d
3 changed files with 22 additions and 62 deletions
|
@ -18,32 +18,6 @@
|
||||||
|
|
||||||
namespace AK {
|
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 {
|
class RefCountedBase {
|
||||||
AK_MAKE_NONCOPYABLE(RefCountedBase);
|
AK_MAKE_NONCOPYABLE(RefCountedBase);
|
||||||
AK_MAKE_NONMOVABLE(RefCountedBase);
|
AK_MAKE_NONMOVABLE(RefCountedBase);
|
||||||
|
@ -87,13 +61,17 @@ class RefCounted : public RefCountedBase {
|
||||||
public:
|
public:
|
||||||
bool unref() const
|
bool unref() const
|
||||||
{
|
{
|
||||||
|
auto const* that = static_cast<T const*>(this);
|
||||||
|
|
||||||
auto new_ref_count = deref_base();
|
auto new_ref_count = deref_base();
|
||||||
if (new_ref_count == 0) {
|
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);
|
delete static_cast<const T*>(this);
|
||||||
return true;
|
return true;
|
||||||
} else if (new_ref_count == 1) {
|
} 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,12 @@ class ListedRefCounted : public RefCountedBase {
|
||||||
public:
|
public:
|
||||||
bool unref() const
|
bool unref() const
|
||||||
{
|
{
|
||||||
|
auto const* that = static_cast<T const*>(this);
|
||||||
|
|
||||||
auto callback = [&](auto& list) {
|
auto callback = [&](auto& list) {
|
||||||
auto new_ref_count = deref_base();
|
auto new_ref_count = deref_base();
|
||||||
if (new_ref_count == 0)
|
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;
|
return new_ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,10 +40,12 @@ public:
|
||||||
else if constexpr (Lock == LockType::Mutex)
|
else if constexpr (Lock == LockType::Mutex)
|
||||||
new_ref_count = T::all_instances().with_exclusive(callback);
|
new_ref_count = T::all_instances().with_exclusive(callback);
|
||||||
if (new_ref_count == 0) {
|
if (new_ref_count == 0) {
|
||||||
call_will_be_destroyed_if_present(static_cast<const T*>(this));
|
if constexpr (requires { that->will_be_destroyed(); })
|
||||||
delete const_cast<T*>(static_cast<T const*>(this));
|
that->will_be_destroyed();
|
||||||
|
delete that;
|
||||||
} else if (new_ref_count == 1) {
|
} 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;
|
return new_ref_count == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,32 +15,6 @@
|
||||||
|
|
||||||
namespace AK {
|
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 {
|
class RefCountedBase {
|
||||||
AK_MAKE_NONCOPYABLE(RefCountedBase);
|
AK_MAKE_NONCOPYABLE(RefCountedBase);
|
||||||
AK_MAKE_NONMOVABLE(RefCountedBase);
|
AK_MAKE_NONMOVABLE(RefCountedBase);
|
||||||
|
@ -95,14 +69,18 @@ class RefCounted : public RefCountedBase {
|
||||||
public:
|
public:
|
||||||
bool unref() const
|
bool unref() const
|
||||||
{
|
{
|
||||||
|
auto const* that = static_cast<T const*>(this);
|
||||||
auto new_ref_count = deref_base();
|
auto new_ref_count = deref_base();
|
||||||
if (new_ref_count == 0) {
|
if (new_ref_count == 0) {
|
||||||
call_will_be_destroyed_if_present(static_cast<const T*>(this));
|
if constexpr (requires { that->will_be_destroyed(); })
|
||||||
delete static_cast<const T*>(this);
|
that->will_be_destroyed();
|
||||||
|
delete that;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (new_ref_count == 1)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue