/* * Copyright (c) 2018-2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace AK { template class Weakable; template class WeakPtr; class WeakLink : public RefCounted { template friend class Weakable; template friend class WeakPtr; public: template RefPtr strong_ref() const requires(IsBaseOf) { return static_cast(m_ptr); } template T* unsafe_ptr() const { return static_cast(m_ptr); } bool is_null() const { return m_ptr == nullptr; } void revoke() { m_ptr = nullptr; } static FlatPtr ptr_offset() { return OFFSET_OF(WeakLink, m_ptr); } private: template explicit WeakLink(T& weakable) : m_ptr(&weakable) { } mutable void* m_ptr { nullptr }; }; template class Weakable { private: class Link; public: template WeakPtr make_weak_ptr() const { return MUST(try_make_weak_ptr()); } template ErrorOr> try_make_weak_ptr() const; protected: Weakable() = default; ~Weakable() { revoke_weak_ptrs(); } void revoke_weak_ptrs() { if (auto link = move(m_link)) link->revoke(); } private: mutable RefPtr m_link; }; } #if USING_AK_GLOBALLY using AK::Weakable; #endif