AK: Add test for the will_be_destroyed and one_ref_left magic functions

Fixes a regression introduced by 5c1b3ce. The commit description there
asserts that the changes allow calling will_be_destroyed and
one_ref_left, which are not required to be const qualified. The
implementation in fact does require the methods to be const qualified,
because we forgot to add the const_cast inside the decltypes :^)
This commit is contained in:
Andrew Kaster 2020-12-05 19:47:20 -07:00 committed by Andreas Kling
parent 765d2977bc
commit 6919639190
2 changed files with 32 additions and 2 deletions

View file

@ -36,7 +36,7 @@
namespace AK {
template<class T>
constexpr auto call_will_be_destroyed_if_present(const T* object) -> decltype(object->will_be_destroyed(), TrueType {})
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 {};
@ -48,7 +48,7 @@ constexpr auto call_will_be_destroyed_if_present(...) -> FalseType
}
template<class T>
constexpr auto call_one_ref_left_if_present(const T* object) -> decltype(object->one_ref_left(), TrueType {})
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 {};

View file

@ -36,6 +36,15 @@ struct Object : public RefCounted<Object> {
struct Object2 : Object {
};
struct SelfAwareObject : public RefCounted<SelfAwareObject> {
void one_ref_left() { m_has_one_ref_left = true; }
void will_be_destroyed() { ++num_destroyed; }
bool m_has_one_ref_left = false;
static size_t num_destroyed;
};
size_t SelfAwareObject::num_destroyed = 0;
TEST_CASE(basics)
{
RefPtr<Object> object = adopt(*new Object);
@ -131,4 +140,25 @@ TEST_CASE(assign_copy_self)
EXPECT_EQ(object->ref_count(), 1u);
}
TEST_CASE(self_observers)
{
RefPtr<SelfAwareObject> object = adopt(*new SelfAwareObject);
EXPECT_EQ(object->ref_count(), 1u);
EXPECT_EQ(object->m_has_one_ref_left, false);
EXPECT_EQ(SelfAwareObject::num_destroyed, 0u);
object->ref();
EXPECT_EQ(object->ref_count(), 2u);
EXPECT_EQ(object->m_has_one_ref_left, false);
EXPECT_EQ(SelfAwareObject::num_destroyed, 0u);
object->unref();
EXPECT_EQ(object->ref_count(), 1u);
EXPECT_EQ(object->m_has_one_ref_left, true);
EXPECT_EQ(SelfAwareObject::num_destroyed, 0u);
object->unref();
EXPECT_EQ(SelfAwareObject::num_destroyed, 1u);
}
TEST_MAIN(RefPtr)