/* * Copyright (c) 2026, the Ladybird developers. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace GC::Detail { template struct RootableValueTraits { static constexpr bool is_rootable = IsBaseOf || IsConvertible; static Cell* cell(T const& value) { if constexpr (IsBaseOf) { if (value.is_cell()) return &const_cast(value).as_cell(); } else if constexpr (IsConvertible) { return const_cast(static_cast(value)); } return nullptr; } }; template struct RootableValueTraits> { static constexpr bool is_rootable = true; static Cell* cell(Ref const& value) { return const_cast(reinterpret_cast(value.ptr())); } }; template struct RootableValueTraits> { static constexpr bool is_rootable = true; static Cell* cell(Ptr const& value) { return const_cast(reinterpret_cast(value.ptr())); } }; template static void gather_root(HashMap& roots, T const& value, HeapRoot::Type root_type) { if (auto* cell = RootableValueTraits::cell(value)) roots.set(cell, HeapRoot { .type = root_type }); } }