1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-05 21:14:49 +00:00
serenity/AK/RefCounted.h
Ben Wiederhake c2a900b853 Everywhere: Remove unused includes of AK/StdLibExtras.h
These instances were detected by searching for files that include
AK/StdLibExtras.h, but don't match the regex:

\\b(abs|AK_REPLACED_STD_NAMESPACE|array_size|ceil_div|clamp|exchange|for
ward|is_constant_evaluated|is_power_of_two|max|min|mix|move|_RawPtr|RawP
tr|round_up_to_power_of_two|swap|to_underlying)\\b

(Without the linebreaks.)

This regex is pessimistic, so there might be more files that don't
actually use any "extra stdlib" functions.

In theory, one might use LibCPP to detect things like this
automatically, but let's do this one step after another.
2023-01-02 20:27:20 -05:00

78 lines
1.6 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Assertions.h>
#include <AK/Checked.h>
#include <AK/Noncopyable.h>
#include <AK/Platform.h>
namespace AK {
class RefCountedBase {
AK_MAKE_NONCOPYABLE(RefCountedBase);
AK_MAKE_NONMOVABLE(RefCountedBase);
public:
using RefCountType = unsigned int;
using AllowOwnPtr = FalseType;
ALWAYS_INLINE void ref() const
{
VERIFY(m_ref_count > 0);
VERIFY(!Checked<RefCountType>::addition_would_overflow(m_ref_count, 1));
++m_ref_count;
}
[[nodiscard]] bool try_ref() const
{
if (m_ref_count == 0)
return false;
ref();
return true;
}
[[nodiscard]] RefCountType ref_count() const { return m_ref_count; }
protected:
RefCountedBase() = default;
~RefCountedBase() { VERIFY(!m_ref_count); }
ALWAYS_INLINE RefCountType deref_base() const
{
VERIFY(m_ref_count);
return --m_ref_count;
}
RefCountType mutable m_ref_count { 1 };
};
template<typename T>
class RefCounted : public RefCountedBase {
public:
bool unref() const
{
auto* that = const_cast<T*>(static_cast<T const*>(this));
auto new_ref_count = deref_base();
if (new_ref_count == 0) {
if constexpr (requires { that->will_be_destroyed(); })
that->will_be_destroyed();
delete static_cast<T const*>(this);
return true;
}
return false;
}
};
}
#if USING_AK_GLOBALLY
using AK::RefCounted;
using AK::RefCountedBase;
#endif