diff --git a/AK/RefCounted.h b/AK/RefCounted.h index 77b480bdbf..d18395904b 100644 --- a/AK/RefCounted.h +++ b/AK/RefCounted.h @@ -36,7 +36,7 @@ namespace AK { template -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(object)->will_be_destroyed(), TrueType {}) { const_cast(object)->will_be_destroyed(); return {}; @@ -48,7 +48,7 @@ constexpr auto call_will_be_destroyed_if_present(...) -> FalseType } template -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(object)->one_ref_left(), TrueType {}) { const_cast(object)->one_ref_left(); return {}; diff --git a/AK/Tests/TestRefPtr.cpp b/AK/Tests/TestRefPtr.cpp index 52207f3268..f823944b44 100644 --- a/AK/Tests/TestRefPtr.cpp +++ b/AK/Tests/TestRefPtr.cpp @@ -36,6 +36,15 @@ struct Object : public RefCounted { struct Object2 : Object { }; +struct SelfAwareObject : public RefCounted { + 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 = adopt(*new Object); @@ -131,4 +140,25 @@ TEST_CASE(assign_copy_self) EXPECT_EQ(object->ref_count(), 1u); } +TEST_CASE(self_observers) +{ + RefPtr 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)