/* * Copyright (c) 2024, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace GC { class ConservativeVectorBase { public: virtual ReadonlySpan possible_values() const = 0; protected: explicit ConservativeVectorBase(Heap&); ~ConservativeVectorBase(); ConservativeVectorBase& operator=(ConservativeVectorBase const&); Heap* m_heap { nullptr }; IntrusiveListNode m_list_node; public: using List = IntrusiveList<&ConservativeVectorBase::m_list_node>; }; template class ConservativeVector final : public ConservativeVectorBase , public Vector { public: explicit ConservativeVector(Heap& heap) : ConservativeVectorBase(heap) { } virtual ~ConservativeVector() = default; ConservativeVector(ConservativeVector const& other) : ConservativeVectorBase(*other.m_heap) , Vector(other) { } ConservativeVector(ConservativeVector&& other) : ConservativeVectorBase(*other.m_heap) , Vector(move(static_cast&>(other))) { } ConservativeVector& operator=(ConservativeVector const& other) { Vector::operator=(other); ConservativeVectorBase::operator=(other); return *this; } virtual ReadonlySpan possible_values() const override { static_assert(sizeof(T) >= sizeof(FlatPtr)); return ReadonlySpan { reinterpret_cast(this->data()), this->size() * sizeof(T) / sizeof(FlatPtr), }; } }; }