xo-arena: + insert/erase in DArenaVector

This commit is contained in:
Roland Conybeare 2026-01-11 12:29:12 -05:00
commit ab7b4e330a

View file

@ -53,18 +53,23 @@ namespace xo {
/** create empty vector using @p cfg to configure backing store **/
static DArenaVector map(const ArenaConfig & cfg);
/** true iff vector is emtpy **/
bool empty() const { return size_ == 0; }
size_type size() const { return size_; }
size_type max_size() const { return capacity(); }
size_type capacity() const { return store_.reserved() / sizeof(T); }
T & operator[](size_t i) { return *(this->_address_of(i)); }
const T & operator[](size_t i) const { return *(this->_address_of(i)); }
/** get reference to element at zero-based index @p i. Do not check bounds **/
T & operator[](size_t i) noexcept { return *(this->_address_of(i)); }
const T & operator[](size_t i) const noexcept { return *(this->_address_of(i)); }
/** get reference to element at zero-based index @p i. Do check bounds **/
T & at(size_type i) { _check_valid_index(i); return *(this->_address_of(i)); }
const T & at(size_type i) const { _check_valid_index(i); return *(this->_address_of(i)); }
/** get to at first element of vector. Same as @p end if vector is empty **/
iterator begin() noexcept { return this->_address_of(0); }
/** get iterator to end of vector - "one past the last element" **/
iterator end() noexcept { return this->_address_of(size_); }
const_iterator cbegin() const noexcept { return this->_address_of(0); }
const_iterator begin() const noexcept { return this->cbegin(); }
@ -74,11 +79,20 @@ namespace xo {
constexpr T * data() { return reinterpret_cast<T*>(store_.lo_); }
constexpr const T * data() const { return reinterpret_cast<const T*>(store_.lo_); }
/** reserve space, if possible, for at least @p z elements.
* Always limited by ArenaConfig.size_
**/
void reserve(size_type z);
void resize(size_type z);
void shrink_to_fit();
/** reset vector to empty state **/
void clear();
T & insert(size_type pos, T && x);
T & insert(size_type pos, const T & x);
void erase(size_type pos);
void push_back(T && x);
void push_back(const T & x);
@ -211,19 +225,84 @@ namespace xo {
throw std::out_of_range("DArenaVector index out of bounds");
}
template <typename T>
T &
DArenaVector<T>::insert(size_type pos, T && x) {
{
size_type new_z = size_ + 1;
size_type req_z = new_z * sizeof(T);
store_.expand(req_z);
}
// move elements [i .. z-1] right by one position.
// must proceed in reverse order!
for (size_type ip1 = size_; ip1 > pos; --ip1) {
(*this)[ip1] = std::move((*this)[ip1-1]);
}
T * addr = this->_address_of(pos);
new (addr) T{std::move(x)};
this->size_ = size_ + 1;
return *addr;
}
template <typename T>
T &
DArenaVector<T>::insert(size_type pos, const T & x) {
{
size_type new_z = size_ + 1;
size_type req_z = new_z * sizeof(T);
store_.expand(req_z);
}
// move elements [i .. z-1] right by one position.
// must proceed in reverse order!
for (size_type ip1 = size_; ip1 > pos; --ip1) {
(*this)[ip1] = std::move((*this)[ip1-1]);
}
T * addr = this->_address_of(pos);
new (addr) T{x};
this->size_ = size_ + 1;
return *addr;
}
template <typename T>
void
DArenaVector<T>::erase(size_type pos) {
// move elements [pos+1 .. z-1] left by one position.
if (pos >= size_) [[unlikely]]
return;
for (size_type i = pos; i+1 < size_; ++i) {
(*this)[i] = std::move((*this)[i+1]);
}
--(this->size_);
}
template <typename T>
void
DArenaVector<T>::push_back(T && x) {
size_type z = size_ + 1;
size_type req_z = z * sizeof(T);
store_.expand(req_z);
this->store_.expand(req_z);
T * addr = this->_address_of(size_);
new (addr) T{std::move(x)};
size_ = z;
this->size_ = z;
}
template <typename T>