Add ArenaVector

This commit is contained in:
2025-08-28 13:27:21 -04:00
parent 3d61408976
commit a32356e298

View File

@@ -277,10 +277,14 @@ public:
* @brief Type-safe version of realloc_raw for arrays of type T.
*
* @param ptr Pointer to the existing allocation (must be from this allocator)
* If nullptr, behaves like allocate<T>(new_size)
* @param old_size Size of the existing allocation in number of T objects
* Ignored if ptr is nullptr
* @param new_size Desired new size in number of T objects
* @return Pointer to the reallocated memory (may be the same as ptr or
* different)
* @note Follows standard realloc() semantics: realloc(nullptr, size) ==
* malloc(size)
* @note Prints error to stderr and calls std::abort() if memory allocation
* fails or size overflow occurs
*/
@@ -575,3 +579,44 @@ public:
template <typename U> friend class ArenaStlAllocator;
};
/// Simple arena-aware vector that doesn't have a destructor
/// Safe to return as span because both the vector and its data are
/// arena-allocated Uses arena's realloc() for efficient growth without copying
/// when possible
template <typename T> struct ArenaVector {
explicit ArenaVector(ArenaAllocator *arena)
: arena_(arena), data_(nullptr), size_(0), capacity_(0) {}
void push_back(const T &item) {
if (size_ >= capacity_) {
grow();
}
data_[size_++] = item;
}
T *data() { return data_; }
const T *data() const { return data_; }
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
T &operator[](size_t index) { return data_[index]; }
const T &operator[](size_t index) const { return data_[index]; }
// No destructor - arena cleanup handles memory
private:
void grow() {
size_t new_capacity = capacity_ == 0 ? 8 : capacity_ * 2;
// arena.realloc() handles nullptr like standard realloc() - acts like
// malloc() This avoids copying when growing in-place is possible
data_ = arena_->realloc(data_, capacity_, new_capacity);
capacity_ = new_capacity;
}
ArenaAllocator *arena_;
T *data_;
size_t size_;
size_t capacity_;
};