12 #ifndef ROC_CORE_ARRAY_H_
13 #define ROC_CORE_ARRAY_H_
100 "array: subscript out of range: index=%lu size=%lu",
101 (
unsigned long)index, (
unsigned long)size_);
111 "array: subscript out of range: index=%lu size=%lu",
112 (
unsigned long)index, (
unsigned long)size_);
138 return data_[size_ - 1];
146 return data_[size_ - 1];
159 new (data_ + size_) T(value);
174 data_[size_ - 1].~T();
185 if (!
grow(new_size)) {
190 for (
size_t n = size_; n < new_size; n++) {
195 for (
size_t n = size_; n > new_size; n--) {
218 if (min_capacity <= capacity_) {
222 T* new_data = allocate_(min_capacity);
227 if (new_data != data_) {
229 for (
size_t n = 0; n < size_; n++) {
230 new (new_data + n) T(data_[n]);
234 for (
size_t n = size_; n > 0; n--) {
246 capacity_ = min_capacity;
259 if (min_capacity <= capacity_) {
263 const size_t new_capacity = next_capacity_(min_capacity);
265 return grow(new_capacity);
269 T* allocate_(
size_t n_elems) {
272 if (n_elems <= EmbeddedCapacity) {
273 data = (T*)embedded_data_.memory();
280 "array: can't allocate memory:"
281 " current_cap=%lu requested_cap=%lu embedded_cap=%lu",
282 (
unsigned long)capacity_, (
unsigned long)n_elems,
283 (
unsigned long)EmbeddedCapacity);
289 void deallocate_(T*
data) {
290 if ((
void*)
data != (
void*)embedded_data_.memory()) {
295 size_t next_capacity_(
size_t min_size)
const {
296 size_t new_capacity = capacity_;
298 if (capacity_ < 1024) {
299 while (min_size > new_capacity) {
300 new_capacity = (new_capacity == 0) ? 2 : new_capacity * 2;
303 while (min_size > new_capacity) {
304 new_capacity += new_capacity / 4;
317 AlignedStorage<EmbeddedCapacity *
sizeof(T)> embedded_data_;
#define ROC_ATTR_NODISCARD
Emit warning if function result is not checked.
const T & front() const
Get const reference to first element.
const T * data() const
Get pointer to first element.
void pop_back()
Remove last element from the array.
void clear()
Set array size to zero.
ROC_ATTR_NODISCARD bool push_back(const T &value)
Append element to array.
T * data()
Get pointer to first element.
Array(IArena &arena)
Initialize empty array with arena.
const T & back() const
Get const reference to last element.
ROC_ATTR_NODISCARD bool grow_exp(size_t min_capacity)
Increase array capacity exponentially.
T & operator[](size_t index)
Get element at given position.
bool is_empty() const
Check if size is zero.
ROC_ATTR_NODISCARD bool grow(size_t min_capacity)
Increase array capacity.
T & back()
Get reference to last element.
size_t capacity() const
Get maximum number of elements that can be added without reallocation.
const T & operator[](size_t index) const
Get element at given position.
T & front()
Get reference to first element.
ROC_ATTR_NODISCARD bool resize(size_t new_size)
Set array size.
size_t size() const
Get number of elements.
virtual void deallocate(void *ptr)=0
Deallocate previously allocated memory.
virtual void * allocate(size_t size)=0
Allocate memory.
Base class for non-copyable objects.
#define roc_log(level,...)
Print message to log.
#define roc_panic_if_msg(x,...)
Panic if condition is true, printing custom message.
#define roc_panic(...)
Print error message and terminate program gracefully.
Commonly used types and functions.