arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
Vector.h
1#pragma once
2#ifdef USE_INITIALIZER_LIST
3#include "InitializerList.h"
4#endif
5#include <assert.h>
6
7#include "Allocator.h"
8
9namespace audio_tools {
10
20template <class T>
21class Vector {
22 public:
29 class iterator {
30 protected:
31 T *ptr;
32 size_t pos_;
33
34 public:
35 iterator() {}
36 iterator(T *parPtr, size_t pos) {
37 this->ptr = parPtr;
38 this->pos_ = pos;
39 }
40 // copy constructor
41 iterator(const iterator &copyFrom) {
42 ptr = copyFrom.ptr;
43 pos_ = copyFrom.pos_;
44 }
45 iterator operator++(int n) {
46 ptr++;
47 pos_++;
48 return *this;
49 }
50 iterator operator++() {
51 ptr++;
52 pos_++;
53 return *this;
54 }
55 iterator operator--(int n) {
56 ptr--;
57 pos_--;
58 return *this;
59 }
60 iterator operator--() {
61 ptr--;
62 pos_--;
63 return *this;
64 }
65 iterator operator+(int offset) {
66 pos_ += offset;
67 return iterator(ptr + offset, offset);
68 }
69 bool operator==(iterator it) { return ptr == it.getPtr(); }
70 bool operator<(iterator it) { return ptr < it.getPtr(); }
71 bool operator<=(iterator it) { return ptr <= it.getPtr(); }
72 bool operator>(iterator it) { return ptr > it.getPtr(); }
73 bool operator>=(iterator it) { return ptr >= it.getPtr(); }
74 bool operator!=(iterator it) { return ptr != it.getPtr(); }
75 T &operator*() { return *ptr; }
76 T *operator->() { return ptr; }
77 T *getPtr() { return ptr; }
78 size_t pos() { return pos_; }
79 size_t operator-(iterator it) { return (ptr - it.getPtr()); }
80 };
81
82#ifdef USE_INITIALIZER_LIST
83
85 Vector(std::initializer_list<T> iniList) {
86 resize(iniList.size());
87 int pos = 0;
88 for (auto &obj : iniList) {
89 p_data[pos++] = obj;
90 }
91 }
92
93#endif
94
96 Vector(size_t len = 0, Allocator &allocator = DefaultAllocator) {
97 setAllocator(allocator);
98 resize_internal(len, false, false);
99 }
100
101
103 Vector(Allocator &allocator) {
104 setAllocator(allocator);
105 }
106
108 Vector(int size, T value, Allocator &allocator = DefaultAllocator) {
109 setAllocator(allocator);
110 resize(size);
111 for (int j = 0; j < size; j++) {
112 p_data[j] = value;
113 }
114 }
115
117 Vector(Vector<T> &&moveFrom) {
118 swap(moveFrom);
119 moveFrom.clear();
120 };
121
123 Vector &operator=(Vector &&moveFrom) {
124 swap(moveFrom);
125 moveFrom.clear();
126 return *this;
127 }
128
130 Vector(Vector<T> &copyFrom) {
131 this->p_allocator = copyFrom.p_allocator;
132 resize_internal(copyFrom.size(), false);
133 for (int j = 0; j < copyFrom.size(); j++) {
134 p_data[j] = copyFrom[j];
135 }
136 this->len = copyFrom.size();
137 }
138
140 template <typename TT, int N>
141 Vector(TT (&a)[N]) {
142 resize_internal(N, false);
143 for (int j = 0; j < N; j++) {
144 p_data[j] = a[j];
145 }
146 this->len = N;
147 }
148
151 resize_internal(copyFrom.size(), false);
152 for (int j = 0; j < copyFrom.size(); j++) {
153 p_data[j] = copyFrom[j];
154 }
155 this->len = copyFrom.size();
156 return *this;
157 }
158
160 Vector(T *from, T *to, Allocator &allocator = DefaultAllocator) {
161 this->p_allocator = &allocator;
162 this->len = to - from;
163 resize_internal(this->len, false);
164 for (size_t j = 0; j < this->len; j++) {
165 p_data[j] = from[j];
166 }
167 }
168
170 virtual ~Vector() { reset(); }
171
172 void setAllocator(Allocator &allocator) {
173 p_allocator = &allocator;
174 }
175
176 void clear() { len = 0; }
177
178 int size() { return len; }
179
180 bool empty() { return size() == 0; }
181
182 void push_back(T &&value) {
183 resize_internal(len + 1, true);
184 p_data[len] = value;
185 len++;
186 }
187
188 void push_back(T &value) {
189 resize_internal(len + 1, true);
190 p_data[len] = value;
191 len++;
192 }
193
194 void push_front(T &value) {
195 resize_internal(len + 1, true);
196 // memmove(p_data,p_data+1,len*sizeof(T));
197 for (int j = len; j >= 0; j--) {
198 p_data[j + 1] = p_data[j];
199 }
200 p_data[0] = value;
201 len++;
202 }
203
204 void push_front(T &&value) {
205 resize_internal(len + 1, true);
206 // memmove(p_data,p_data+1,len*sizeof(T));
207 for (int j = len; j >= 0; j--) {
208 p_data[j + 1] = p_data[j];
209 }
210 p_data[0] = value;
211 len++;
212 }
213
214 void pop_back() {
215 if (len > 0) {
216 len--;
217 }
218 }
219
220 void pop_front() { erase(0); }
221
222 void assign(iterator v1, iterator v2) {
223 size_t newLen = v2 - v1;
224 resize_internal(newLen, false);
225 this->len = newLen;
226 int pos = 0;
227 for (auto ptr = v1; ptr != v2; ptr++) {
228 p_data[pos++] = *ptr;
229 }
230 }
231
232 void assign(size_t number, T value) {
233 resize_internal(number, false);
234 this->len = number;
235 for (int j = 0; j < number; j++) {
236 p_data[j] = value;
237 }
238 }
239
240 void swap(Vector<T> &in) {
241 // save data
242 T *dataCpy = p_data;
243 int bufferLenCpy = bufferLen;
244 int lenCpy = len;
245 // swap this
246 p_data = in.p_data;
247 len = in.len;
248 bufferLen = in.bufferLen;
249 // swp in
250 in.p_data = dataCpy;
251 in.len = lenCpy;
252 in.bufferLen = bufferLenCpy;
253 }
254
255 T &operator[](int index) {
256 assert(p_data != nullptr);
257 assert(index < len);
258 return p_data[index];
259 }
260
261 T &operator[](const int index) const {
262 assert(index < len);
263 return p_data[index];
264 }
265
266 bool resize(int newSize, T value) {
267 if (resize(newSize)) {
268 for (int j = 0; j < newSize; j++) {
269 p_data[j] = value;
270 }
271 return true;
272 }
273 return false;
274 }
275
276 void shrink_to_fit() { resize_internal(this->len, true, true); }
277
278 int capacity() { return this->bufferLen; }
279
280 bool resize(int newSize) {
281 int oldSize = this->len;
282 resize_internal(newSize, true);
283 this->len = newSize;
284 return this->len != oldSize;
285 }
286
287 iterator begin() { return iterator(p_data, 0); }
288
289 T &back() { return *iterator(p_data + (len - 1), len - 1); }
290
291 iterator end() { return iterator(p_data + len, len); }
292
293 // removes a single element
294 void erase(iterator it) { return erase(it.pos()); }
295
296 // removes a single element
297 void erase(int pos) {
298 if (pos < len) {
299 int lenToEnd = len - pos - 1;
300 // call destructor on data to be erased
301 p_data[pos].~T();
302 // shift values by 1 position
303 memmove((void *)&p_data[pos], (void *)(&p_data[pos + 1]),
304 lenToEnd * sizeof(T));
305
306 // make sure that we have a valid object at the end
307#if defined(NO_INPLACE_INIT_SUPPORT)
308 p_data[len - 1] = T();
309#else
310 new (&(p_data[len - 1])) T();
311#endif
312 len--;
313 }
314 }
315
316 T *data() { return p_data; }
317
318 operator bool() const { return p_data != nullptr; }
319
320 int indexOf(T obj) {
321 for (int j = 0; j < size(); j++) {
322 if (p_data[j] == obj) return j;
323 }
324 return -1;
325 }
326
327 bool contains(T obj){
328 return indexOf(obj) >= 0;
329 }
330
331
332 void swap(T &other) {
333 // save values
334 int temp_blen = bufferLen;
335 int temp_len = len;
336 T *temp_data = p_data;
337 // swap from other
338 bufferLen = other.bufferLen;
339 len = other.len;
340 p_data = other.p_data;
341 // set other
342 other.bufferLen = temp_blen;
343 other.len = temp_len;
344 other.p_data = temp_data;
345 }
346
347 void reset() {
348 clear();
349 shrink_to_fit();
350 deleteArray(p_data, size()); // delete [] this->p_data;
351 p_data = nullptr;
352 }
353
354 protected:
355 int bufferLen = 0;
356 int len = 0;
357 T *p_data = nullptr;
358 Allocator *p_allocator = &DefaultAllocator;
359
360 void resize_internal(int newSize, bool copy, bool shrink = false) {
361 if (newSize <= 0) return;
362 if (newSize > bufferLen || this->p_data == nullptr || shrink) {
363 T *oldData = p_data;
364 int oldBufferLen = this->bufferLen;
365 p_data = newArray(newSize); // new T[newSize+1];
366 assert(p_data != nullptr);
367 this->bufferLen = newSize;
368 if (oldData != nullptr) {
369 if (copy && this->len > 0) {
370 // save existing data
371 memmove((void*)p_data, (void*)oldData, len * sizeof(T));
372 // clear to prevent double release
373 memset((void*)oldData, 0, len * sizeof(T));
374 }
375 if (shrink) {
376 cleanup(oldData, newSize, oldBufferLen);
377 }
378 deleteArray(oldData, oldBufferLen); // delete [] oldData;
379 }
380 }
381 }
382
383 T *newArray(int newSize) {
384 T *data;
385#if USE_ALLOCATOR
386 data = p_allocator->createArray<T>(newSize); // new T[newSize+1];
387#else
388 data = new T[newSize];
389#endif
390 return data;
391 }
392
393 void deleteArray(T *oldData, int oldBufferLen) {
394#if USE_ALLOCATOR
395 p_allocator->removeArray(oldData, oldBufferLen); // delete [] oldData;
396#else
397 delete[] oldData;
398#endif
399 }
400
401
402 void cleanup(T *data, int from, int to) {
403 for (int j = from; j < to; j++) {
404 data[j].~T();
405 }
406 }
407};
408
409} // namespace audio_tools
Memory allocateator which uses malloc.
Definition Allocator.h:23
Iterator for the Vector class.
Definition Vector.h:29
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Vector(T *from, T *to, Allocator &allocator=DefaultAllocator)
legacy constructor with pointer range
Definition Vector.h:160
Vector(Vector< T > &&moveFrom)
Move constructor.
Definition Vector.h:117
Vector< T > & operator=(Vector< T > &copyFrom)
copy operator
Definition Vector.h:150
virtual ~Vector()
Destructor.
Definition Vector.h:170
Vector(int size, T value, Allocator &allocator=DefaultAllocator)
Allocate size and initialize array.
Definition Vector.h:108
Vector & operator=(Vector &&moveFrom)
Move operator.
Definition Vector.h:123
Vector(Vector< T > &copyFrom)
copy constructor
Definition Vector.h:130
Vector(TT(&a)[N])
convert from c array
Definition Vector.h:141
Vector(size_t len=0, Allocator &allocator=DefaultAllocator)
Default constructor: size 0 with DefaultAllocator: The len defines the capacity.
Definition Vector.h:96
Vector(Allocator &allocator)
Constructor with only allocator.
Definition Vector.h:103
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10