12#ifndef ROC_CORE_ARRAY_H_
13#define ROC_CORE_ARRAY_H_
55 , allocator_(&allocator) {
101 if (index >= size_) {
102 roc_panic(
"array: subscript out of range: index=%lu size=%lu",
103 (
unsigned long)index, (
unsigned long)size_);
110 if (index >= size_) {
111 roc_panic(
"array: subscript out of range: index=%lu size=%lu",
112 (
unsigned long)index, (
unsigned long)size_);
121 if (size_ >= max_size_) {
122 roc_panic(
"array: attempting to append element to full array: size=%lu",
123 (
unsigned long)size_);
125 new (data_ + size_) T(value);
141 for (
size_t n = size_; n < sz; n++) {
146 for (
size_t n = size_; n > sz; n--) {
162 if (max_sz <= max_size_) {
166 T* new_data = allocate_(max_sz);
168 roc_log(
LogError,
"array: can't allocate memory: old_size=%lu new_size=%lu",
169 (
unsigned long)max_size_, (
unsigned long)max_sz);
173 if (new_data != data_) {
175 for (
size_t n = 0; n < size_; n++) {
176 new (new_data + n) T(data_[n]);
180 for (
size_t n = size_; n > 0; n--) {
205 if (min_size <= max_size_) {
209 size_t new_max_size_ = max_size_;
211 if (max_size_ < 1024) {
212 while (min_size > new_max_size_) {
213 new_max_size_ = (new_max_size_ == 0) ? 2 : new_max_size_ * 2;
216 while (min_size > new_max_size_) {
217 new_max_size_ += new_max_size_ / 4;
221 return grow(new_max_size_);
225 T* allocate_(
size_t n_elems) {
226 if (n_elems <= EmbeddedCapacity) {
227 return (T*)embedded_data_.memory();
228 }
else if (allocator_) {
229 return (T*)allocator_->
allocate(n_elems *
sizeof(T));
235 void deallocate_(T*
data) {
236 if ((
void*)
data != (
void*)embedded_data_.memory()) {
246 IAllocator* allocator_;
248 AlignedStorage<EmbeddedCapacity *
sizeof(T)> embedded_data_;
bool grow_exp(size_t min_size)
Increase array capacity exponentially.
T * data()
Get pointer to first element.
Array()
Initialize empty array without allocator.
const T * data() const
Get pointer to first element.
Array(IAllocator &allocator)
Initialize empty array.
bool grow(size_t max_sz)
Increase array capacity.
void push_back(const T &value)
Append element to array.
size_t capacity() const
Get maximum number of elements. If array has allocator, capacity can be grown.
const T & operator[](size_t index) const
Get element at given position.
T & operator[](size_t index)
Get element at given position.
bool resize(size_t sz)
Set array size.
size_t size() const
Get number of elements.
Memory allocator interface.
virtual void deallocate(void *)=0
Deallocate previously allocated memory.
virtual void * allocate(size_t size)=0
Allocate memory.
Base class for non-copyable objects.
Memory allocator interface.
#define roc_log(level,...)
Print message to log.
#define roc_panic_if(x)
Panic if condition is true.
#define roc_panic(...)
Print error message and terminate program gracefully.
Commonly used types and functions.