/* * 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 MarkedVectorBase { public: virtual void gather_roots(HashMap&) const = 0; protected: explicit MarkedVectorBase(Heap&); ~MarkedVectorBase(); MarkedVectorBase& operator=(MarkedVectorBase const&); Heap* m_heap { nullptr }; IntrusiveListNode m_list_node; public: using List = IntrusiveList<&MarkedVectorBase::m_list_node>; }; template class MarkedVector final : public MarkedVectorBase , public Vector { public: explicit MarkedVector(Heap& heap) : MarkedVectorBase(heap) { } virtual ~MarkedVector() = default; MarkedVector(MarkedVector const& other) : MarkedVectorBase(*other.m_heap) , Vector(other) { } MarkedVector(MarkedVector&& other) : MarkedVectorBase(*other.m_heap) , Vector(move(static_cast&>(other))) { } MarkedVector& operator=(MarkedVector const& other) { Vector::operator=(other); MarkedVectorBase::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::MarkedVector }); } else { roots.set(value, HeapRoot { .type = HeapRoot::Type::MarkedVector }); } } } }; }