/* * Copyright (c) 2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace JS { class HandleImpl : public RefCounted { AK_MAKE_NONCOPYABLE(HandleImpl); AK_MAKE_NONMOVABLE(HandleImpl); public: ~HandleImpl(); Cell* cell() { return m_cell; } const Cell* cell() const { return m_cell; } private: template friend class Handle; explicit HandleImpl(Cell*); Cell* m_cell { nullptr }; IntrusiveListNode m_list_node; public: using List = IntrusiveList<&HandleImpl::m_list_node>; }; template class Handle { public: Handle() = default; static Handle create(T* cell) { return Handle(adopt_ref(*new HandleImpl(cell))); } T* cell() { return static_cast(m_impl->cell()); } const T* cell() const { return static_cast(m_impl->cell()); } bool is_null() const { return m_impl.is_null(); } private: explicit Handle(NonnullRefPtr impl) : m_impl(move(impl)) { } RefPtr m_impl; }; template inline Handle make_handle(T* cell) { return Handle::create(cell); } }