Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
Loading...
Searching...
No Matches
array.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 Roc authors
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 */
8
9//! @file roc_core/array.h
10//! @brief Dynamic array.
11
12#ifndef ROC_CORE_ARRAY_H_
13#define ROC_CORE_ARRAY_H_
14
15#include "roc_core/iallocator.h"
16#include "roc_core/log.h"
18#include "roc_core/panic.h"
19#include "roc_core/stddefs.h"
20
21namespace roc {
22namespace core {
23
24//! Dynamic array.
25template <class T> class Array : public NonCopyable<> {
26public:
27 //! Initialize empty array.
28 explicit Array(IAllocator& allocator)
29 : data_(NULL)
30 , size_(0)
31 , max_size_(0)
32 , allocator_(allocator) {
33 }
34
35 ~Array() {
36 resize(0);
37
38 if (data_) {
39 allocator_.deallocate(data_);
40 }
41 }
42
43 //! Get maximum number of elements.
44 size_t max_size() const {
45 return max_size_;
46 }
47
48 //! Get number of elements.
49 size_t size() const {
50 return size_;
51 }
52
53 //! Get element at given position.
54 T& operator[](size_t index) {
55 if (index >= size_) {
56 roc_panic("array: subscript out of range: index=%lu size=%lu",
57 (unsigned long)index, (unsigned long)size_);
58 }
59 return data_[index];
60 }
61
62 //! Get element at given position.
63 const T& operator[](size_t index) const {
64 if (index >= size_) {
65 roc_panic("array: subscript out of range: index=%lu size=%lu",
66 (unsigned long)index, (unsigned long)size_);
67 }
68 return data_[index];
69 }
70
71 //! Get first element.
72 //! @pre
73 //! Array should be non-empty.
74 T& front() {
75 if (size_ == 0) {
76 roc_panic("array: attempting to call front() on empty array");
77 }
78 return data_[0];
79 }
80
81 //! Get first element.
82 //! @pre
83 //! Array should be non-empty.
84 const T& front() const {
85 if (size_ == 0) {
86 roc_panic("array: attempting to call front() on empty array");
87 }
88 return data_[0];
89 }
90
91 //! Get last element.
92 //! @pre
93 //! Array should be non-empty.
94 T& back() {
95 if (size_ == 0) {
96 roc_panic("array: attempting to call back() on empty array");
97 }
98 return data_[size_ - 1];
99 }
100
101 //! Get last element.
102 //! @pre
103 //! Array should be non-empty.
104 const T& back() const {
105 if (size_ == 0) {
106 roc_panic("array: attempting to call back() on empty array");
107 }
108 return data_[size_ - 1];
109 }
110
111 //! Append element to array.
112 //! @pre
113 //! Array size() should be less than max_size().
114 void push_back(const T& value) {
115 if (size_ >= max_size_) {
116 roc_panic("array: attempting to append element to full array: size=%lu",
117 (unsigned long)size_);
118 }
119 new (data_ + size_) T(value);
120 size_++;
121 }
122
123 //! Set array size.
124 //! @remarks
125 //! Calls grow() to ensure that there is enough space in array.
126 //! @returns
127 //! false if the allocation failed
128 bool resize(size_t sz) {
129 // Move objects to a new memory region if necessary.
130 if (!grow(sz)) {
131 return false;
132 }
133
134 // Construct objects if size increased.
135 for (size_t n = size_; n < sz; n++) {
136 new (data_ + n) T();
137 }
138
139 // Destruct objects (in reverse order) if size decreased.
140 for (size_t n = size_; n > sz; n--) {
141 data_[n - 1].~T();
142 }
143
144 size_ = sz;
145
146 return true;
147 }
148
149 //! Increase array maximum size.
150 //! @remarks
151 //! If @p max_sz is greater than the current maximum size, a larger memory
152 //! region is allocated and the array elements are copied there.
153 //! @returns
154 //! false if the allocation failed
155 bool grow(size_t max_sz) {
156 if (max_sz <= max_size_) {
157 return true;
158 }
159
160 T* new_data = (T*)allocator_.allocate(max_sz * sizeof(T));
161 if (!new_data) {
162 roc_log(LogError, "array: can't allocate memory: old_size=%lu new_size=%lu",
163 (unsigned long)max_size_, (unsigned long)max_sz);
164 return false;
165 }
166
167 // Copy objects.
168 for (size_t n = 0; n < size_; n++) {
169 new (new_data + n) T(data_[n]);
170 }
171
172 // Destruct objects (in reverse order).
173 for (size_t n = size_; n > 0; n--) {
174 data_[n - 1].~T();
175 }
176
177 if (data_) {
178 allocator_.deallocate(data_);
179 }
180
181 data_ = new_data;
182 max_size_ = max_sz;
183
184 return true;
185 }
186
187private:
188 T* data_;
189 size_t size_;
190 size_t max_size_;
191 IAllocator& allocator_;
192};
193
194} // namespace core
195} // namespace roc
196
197#endif // ROC_CORE_ARRAY_H_
Dynamic array.
Definition: array.h:25
bool grow(size_t max_sz)
Increase array maximum size.
Definition: array.h:155
const T & front() const
Get first element.
Definition: array.h:84
void push_back(const T &value)
Append element to array.
Definition: array.h:114
T & back()
Get last element.
Definition: array.h:94
bool resize(size_t sz)
Set array size.
Definition: array.h:128
T & front()
Get first element.
Definition: array.h:74
Array(IAllocator &allocator)
Initialize empty array.
Definition: array.h:28
const T & back() const
Get last element.
Definition: array.h:104
size_t max_size() const
Get maximum number of elements.
Definition: array.h:44
T & operator[](size_t index)
Get element at given position.
Definition: array.h:54
const T & operator[](size_t index) const
Get element at given position.
Definition: array.h:63
size_t size() const
Get number of elements.
Definition: array.h:49
Memory allocator interface.
Definition: iallocator.h:23
virtual void deallocate(void *)=0
Deallocate previously allocated memory.
virtual void * allocate(size_t size)=0
Allocate memory.
Base class for non-copyable objects.
Definition: noncopyable.h:23
Memory allocator interface.
Logging.
#define roc_log(...)
Print message to log.
Definition: log.h:25
Root namespace.
@ LogError
Error message.
Definition: log.h:33
Non-copyable object.
Panic function.
#define roc_panic(...)
Print error message and terminate program gracefully.
Definition: panic.h:42
Commonly used types and functions.