xo-arena: + insert/erase in DArenaVector
This commit is contained in:
parent
016ddf730f
commit
0366136e82
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 **/
|
/** create empty vector using @p cfg to configure backing store **/
|
||||||
static DArenaVector map(const ArenaConfig & cfg);
|
static DArenaVector map(const ArenaConfig & cfg);
|
||||||
|
|
||||||
|
/** true iff vector is emtpy **/
|
||||||
bool empty() const { return size_ == 0; }
|
bool empty() const { return size_ == 0; }
|
||||||
size_type size() const { return size_; }
|
size_type size() const { return size_; }
|
||||||
size_type max_size() const { return capacity(); }
|
size_type max_size() const { return capacity(); }
|
||||||
size_type capacity() const { return store_.reserved() / sizeof(T); }
|
size_type capacity() const { return store_.reserved() / sizeof(T); }
|
||||||
|
|
||||||
T & operator[](size_t i) { return *(this->_address_of(i)); }
|
/** get reference to element at zero-based index @p i. Do not check bounds **/
|
||||||
const T & operator[](size_t i) const { return *(this->_address_of(i)); }
|
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)); }
|
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)); }
|
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); }
|
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_); }
|
iterator end() noexcept { return this->_address_of(size_); }
|
||||||
const_iterator cbegin() const noexcept { return this->_address_of(0); }
|
const_iterator cbegin() const noexcept { return this->_address_of(0); }
|
||||||
const_iterator begin() const noexcept { return this->cbegin(); }
|
const_iterator begin() const noexcept { return this->cbegin(); }
|
||||||
|
|
@ -74,11 +79,20 @@ namespace xo {
|
||||||
constexpr T * data() { return reinterpret_cast<T*>(store_.lo_); }
|
constexpr T * data() { return reinterpret_cast<T*>(store_.lo_); }
|
||||||
constexpr const T * data() const { return reinterpret_cast<const 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 reserve(size_type z);
|
||||||
void resize(size_type z);
|
void resize(size_type z);
|
||||||
void shrink_to_fit();
|
void shrink_to_fit();
|
||||||
|
/** reset vector to empty state **/
|
||||||
void clear();
|
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(T && x);
|
||||||
void push_back(const T & x);
|
void push_back(const T & x);
|
||||||
|
|
||||||
|
|
@ -211,19 +225,84 @@ namespace xo {
|
||||||
throw std::out_of_range("DArenaVector index out of bounds");
|
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>
|
template <typename T>
|
||||||
void
|
void
|
||||||
DArenaVector<T>::push_back(T && x) {
|
DArenaVector<T>::push_back(T && x) {
|
||||||
size_type z = size_ + 1;
|
size_type z = size_ + 1;
|
||||||
size_type req_z = z * sizeof(T);
|
size_type req_z = z * sizeof(T);
|
||||||
|
|
||||||
store_.expand(req_z);
|
this->store_.expand(req_z);
|
||||||
|
|
||||||
T * addr = this->_address_of(size_);
|
T * addr = this->_address_of(size_);
|
||||||
|
|
||||||
new (addr) T{std::move(x)};
|
new (addr) T{std::move(x)};
|
||||||
|
|
||||||
size_ = z;
|
this->size_ = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue