/* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include namespace GC { class GC_API RootVectorBase { public: virtual void gather_roots(HashMap&) const = 0; protected: RootVectorBase(); explicit RootVectorBase(Heap&); ~RootVectorBase(); void assign_heap(Heap*); Heap* m_heap { nullptr }; IntrusiveListNode m_list_node; public: using List = IntrusiveList<&RootVectorBase::m_list_node>; }; template class RootVector final : public RootVectorBase , public Vector { using VectorBase = Vector; public: RootVector() : RootVectorBase() { } ~RootVector() = default; RootVector(ReadonlySpan other) : RootVectorBase() , Vector(other) { } RootVector(RootVector const& other) : RootVectorBase(*other.m_heap) , Vector(other) { } RootVector(RootVector&& other) : RootVectorBase(*other.m_heap) , VectorBase(move(static_cast(other))) { } RootVector& operator=(RootVector const& other) { if (&other == this) return *this; assign_heap(other.m_heap); VectorBase::operator=(other); return *this; } RootVector& operator=(RootVector&& other) { assign_heap(other.m_heap); VectorBase::operator=(move(static_cast(other))); return *this; } virtual void gather_roots(HashMap& roots) const override { static_assert(Detail::RootableValueTraits::is_rootable, "RootVector element type must be convertible to Cell const* or derive from NanBoxedValue"); for (auto& value : *this) Detail::gather_root(roots, value, HeapRoot::Type::RootVector); } }; template RootVector(ReadonlySpan const&) -> RootVector; template RootVector(Span const&) -> RootVector; template RootVector(Vector const&) -> RootVector; }