/* * Copyright (c) 2025, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace GC { class GC_API RootHashMapBase { public: virtual void gather_roots(HashMap&) const = 0; protected: RootHashMapBase(); explicit RootHashMapBase(Heap&); ~RootHashMapBase(); void assign_heap(Heap*); Heap* m_heap { nullptr }; IntrusiveListNode m_list_node; public: using List = IntrusiveList<&RootHashMapBase::m_list_node>; }; template, typename ValueTraits = Traits, bool IsOrdered = false> class RootHashMap final : public RootHashMapBase , public HashMap { using HashMapBase = HashMap; public: RootHashMap() : RootHashMapBase() { } ~RootHashMap() = default; virtual void gather_roots(HashMap& roots) const override { static constexpr bool KeyIsGCType = Detail::RootableValueTraits::is_rootable; static constexpr bool ValueIsGCType = Detail::RootableValueTraits::is_rootable; static_assert(KeyIsGCType || ValueIsGCType, "RootHashMap requires at least one of key or value types to be convertible to Cell const* or derive from NanBoxedValue"); for (auto& [key, value] : *this) { if constexpr (KeyIsGCType) Detail::gather_root(roots, key, HeapRoot::Type::RootHashMap); if constexpr (ValueIsGCType) Detail::gather_root(roots, value, HeapRoot::Type::RootHashMap); } } }; template, typename ValueTraits = Traits> using OrderedRootHashMap = RootHashMap; }