1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2026-01-20 01:21:00 +00:00
serenity/Userland/Libraries/LibJS/Heap/MarkedVector.h
Andreas Kling 8bb9fe63b7 LibJS: Add MarkedVector<T>
This abstracts a vector of Cell* with a strongly typed span() accessor
that gives you Span<T*> instead of Span<Cell*>.

It is intended to replace MarkedValueList in situations where you only
need to store pointers to Cell (or an even more specific type of Cell).

The API can definitely be improved, it's just the bare basics for now.
2021-12-16 22:48:17 +01:00

70 lines
1.5 KiB
C++

/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/IntrusiveList.h>
#include <AK/Noncopyable.h>
#include <AK/Vector.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
namespace JS {
class MarkedVectorBase {
AK_MAKE_NONCOPYABLE(MarkedVectorBase);
public:
void append(Cell* cell) { m_cells.append(cell); }
void prepend(Cell* cell) { m_cells.prepend(cell); }
size_t size() const { return m_cells.size(); }
Span<Cell*> cells() { return m_cells.span(); }
protected:
explicit MarkedVectorBase(Heap&);
MarkedVectorBase(MarkedVectorBase&&);
MarkedVectorBase& operator=(MarkedVectorBase&& other)
{
m_cells = move(other.m_cells);
return *this;
}
~MarkedVectorBase();
Heap& m_heap;
IntrusiveListNode<MarkedVectorBase> m_list_node;
Vector<Cell*> m_cells;
public:
using List = IntrusiveList<&MarkedVectorBase::m_list_node>;
};
template<typename T>
class MarkedVector : public MarkedVectorBase {
public:
explicit MarkedVector(Heap& heap)
: MarkedVectorBase(heap)
{
}
~MarkedVector() = default;
MarkedVector(MarkedVector&&) = default;
MarkedVector& operator=(MarkedVector&&) = default;
Span<T*> span() { return Span<T*> { bit_cast<T**>(m_cells.data()), m_cells.size() }; }
auto begin() { return span().begin(); }
auto begin() const { return span().begin(); }
auto end() { return span().begin(); }
auto end() const { return span().begin(); }
};
}