/* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace GC { class RootVectorBase { public: virtual void gather_roots(HashMap&) const = 0; protected: explicit RootVectorBase(Heap&); ~RootVectorBase(); RootVectorBase& operator=(RootVectorBase const&); Heap* m_heap { nullptr }; IntrusiveListNode m_list_node; public: using List = IntrusiveList<&RootVectorBase::m_list_node>; }; template class RootVector final : public RootVectorBase , public Vector { public: explicit RootVector(Heap& heap) : RootVectorBase(heap) { } virtual ~RootVector() = default; RootVector(Heap& heap, ReadonlySpan other) : RootVectorBase(heap) , Vector(other) { } RootVector(RootVector const& other) : RootVectorBase(*other.m_heap) , Vector(other) { } RootVector(RootVector&& other) : RootVectorBase(*other.m_heap) , Vector(move(static_cast&>(other))) { } RootVector& operator=(RootVector const& other) { Vector::operator=(other); RootVectorBase::operator=(other); return *this; } virtual void gather_roots(HashMap& roots) const override { for (auto& value : *this) { if constexpr (IsBaseOf) { if (value.is_cell()) roots.set(&const_cast(value).as_cell(), HeapRoot { .type = HeapRoot::Type::RootVector }); } else { roots.set(value, HeapRoot { .type = HeapRoot::Type::RootVector }); } } } }; }