xo-arena: + insert/erase in DArenaVector
This commit is contained in:
parent
f7bd3b0db3
commit
ab7b4e330a
1 changed files with 83 additions and 4 deletions
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue