diff --git a/src/arena_allocator.hpp b/src/arena_allocator.hpp index 5ee50b5..6bf99db 100644 --- a/src/arena_allocator.hpp +++ b/src/arena_allocator.hpp @@ -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(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 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 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_; +};