arduino-audio-tools
Loading...
Searching...
No Matches
List.h
Go to the documentation of this file.
1#pragma once
2#ifdef USE_INITIALIZER_LIST
3# include "InitializerList.h"
4#endif
5#include <stddef.h>
6#include <assert.h>
7#include "Allocator.h"
8
9namespace audio_tools {
10
18template <class T>
19class List {
20 public:
21 struct Node {
22 Node* next = nullptr;
23 Node* prior = nullptr;
25 };
26
27 class Iterator {
28 public:
30 this->node = node;
31 }
33 if (node->next!=nullptr){
34 node = node->next;
35 is_eof = false;
36 } else is_eof=true;
37 return *this;
38 }
39 inline Iterator operator++(int) {
40 return ++*this;
41 }
43 if (node->prior!=nullptr){
44 node = node->prior;
45 is_eof = false;
46 } else is_eof=true;
47 return *this;
48 }
49 inline Iterator operator--(int) {
50 return --*this;
51 }
52 inline Iterator operator+(int offset) {
53 return getIteratorAtOffset(offset);
54 }
55 inline Iterator operator-(int offset) {
56 return getIteratorAtOffset(-offset);
57 }
58 inline bool operator==(Iterator it) {
59 return node == it.get_node();
60 }
61 inline bool operator!=(Iterator it) {
62 return node != it.get_node();
63 }
64 inline T &operator*() {
65 return node->data;
66 }
67 inline T *operator->() {
68 return &(node->data);
69 }
70 inline Node *get_node() {
71 return node;
72 }
73 inline operator bool() {
74 return is_eof;
75 }
76 protected:
77 Node* node=nullptr;
78 bool is_eof = false;
79
81 Node *tmp = node;
82 if (offset>0){
83 for (int j=0;j<offset;j++){
84 if (tmp->next==nullptr){
85 return Iterator(tmp);
86 }
87 tmp = tmp->next;
88 }
89 } else if (offset<0){
90 for (int j=0;j<-offset;j++){
91 if (tmp->prior==nullptr){
92 return Iterator(tmp);
93 }
94 tmp = tmp->prior;
95 }
96 }
97 Iterator it(tmp);
98 return it;
99 }
100
101 };
102
105 p_allocator = &allocator;
106 link();
107 };
109 List(List&ref) = default;
110
112 template<size_t N>
113 List(const T (&a)[N], Allocator &allocator=DefaultAllocator) {
114 p_allocator = &allocator;
115 link();
116 for(int i = 0; i < N; ++i)
117 push_back(a[i]);
118 }
119
121 clear();
122 }
123
124#ifdef USE_INITIALIZER_LIST
125
126 List(std::initializer_list<T> iniList) {
127 link();
128 for(auto &obj : iniList)
129 push_back(obj);
130 }
131#endif
132 bool swap(List<T>&ref){
133 List<T> tmp(*this);
134 validate();
135
136 first = ref.first;
137 last = ref.last;
139
140 ref.first = tmp.first;
141 ref.last = tmp.last;
142 ref.record_count = tmp.record_count;
143
144 validate();
145 return true;
146 }
147
148 bool push_back(T data){
149 Node *node = createNode();
150 if (node==nullptr) return false;
151 node->data = data;
152
153 // update links
154 Node *old_last_prior = last.prior;
155 node->next = &last;
156 node->prior = old_last_prior;
157 old_last_prior->next = node;
158 last.prior = node;
159
160 record_count++;
161 validate();
162 return true;
163 }
164
165 bool push_front(T data){
166 Node *node = createNode();
167 if (node==nullptr) return false;
168 node->data = data;
169
170 // update links
171 Node *old_begin_next = first.next;
172 node->prior = &first;
173 node->next = old_begin_next;
174 old_begin_next->prior = node;
175 first.next = node;
176
177 record_count++;
178 validate();
179 return true;
180 }
181
182 bool insert(Iterator it, const T& data){
183 Node *node = createNode();
184 if (node==nullptr) return false;
185 node->data = data;
186
187 // update links
188 Node *current_node = it.get_node();
189 Node *prior = current_node->prior;
190
191 prior->next = node;
192 current_node->prior = node;
193 node->prior = prior;
194 node->next = current_node;
195
196 record_count++;
197 validate();
198 return true;
199 }
200
201
202 bool pop_front(){
203 T tmp;
204 return pop_front(tmp);
205 }
206
207 bool pop_back(){
208 T tmp;
209 return pop_back(tmp);
210 }
211
212 bool pop_front(T &data){
213 if (record_count==0) return false;
214 // get data
215 Node *p_delete = firstDataNode();
216 Node *p_prior = p_delete->prior;
217 Node *p_next = p_delete->next;
218
219 data = p_delete->data;
220
221 // remove last node
222 p_prior->next = p_next;
223 p_next->prior = p_prior;
224
225 deleteNode(p_delete);
226
227 record_count--;
228
229 validate();
230 return true;
231 }
232
233 bool pop_back(T &data){
234 if (record_count==0) return false;
235 Node *p_delete = lastDataNode();
236 Node *p_prior = p_delete->prior;
237 Node *p_next = p_delete->next;
238
239 // get data
240 data = p_delete->data;
241
242 // remove last node
243 p_prior->next = p_next;
244 p_next->prior = p_prior;
245
246 deleteNode(p_delete);
247
248 record_count--;
249
250 validate();
251 return true;
252 }
253
254 bool erase (Iterator it){
255 Node *p_delete = it.get_node();
256 // check for valid iterator
257 if (empty() || p_delete==&first || p_delete==&last){
258 return false;
259 }
260 Node *p_prior = p_delete->prior;
261 Node *p_next = p_delete->next;
262
263 // remove last node
264 p_prior->next = p_next;
265 p_next->prior = p_prior;
266
267 deleteNode(p_delete);
268
269 record_count--;
270 return true;
271 }
272
273
276 return it;
277 }
278
280 Iterator it(&last);
281 return it;
282 }
283
286 return it;
287 }
288
290 Iterator it(&first);
291 return it;
292 }
293
294 size_t size() {
295 return record_count;
296 }
297
298 bool empty() {
299 return size()==0;
300 }
301
302 bool clear() {
303 while(pop_front())
304 ;
305 validate();
306 return true;
307 }
308
309 inline T &operator[](int index) {
310 Node *n = firstDataNode();
311 for (int j=0;j<index;j++){
312 n = n->next;
313 if (n==nullptr){
314 return last.data;
315 }
316 }
317 return n->data;
318 }
319
320 void setAllocator(Allocator &allocator){
321 p_allocator = &allocator;
322 }
323
325 T& front() {
326 return *begin();
327 }
328
330 T& back() {
331 return *rbegin();
332 }
333
334
335 protected:
336 Node first; // empty dummy first node which which is always before the first data node
337 Node last; // empty dummy last node which which is always after the last data node
338 size_t record_count=0;
340
342#if USE_ALLOCATOR
343 Node *node = (Node*) p_allocator->allocate(sizeof(Node));// new Node();
344#else
345 Node *node = new Node();
346#endif
347 return node;
348 }
349
350 void deleteNode(Node* p_delete){
351#if USE_ALLOCATOR
352 p_allocator->free(p_delete); //delete p_delete;
353#else
354 delete p_delete;
355#endif
356
357 }
358
359 void link(){
360 first.next = &last;
361 last.prior = &first;
362 }
363
365 return last.prior;
366 }
368 return first.next;
369 }
370
371 void validate() {
372 assert(first.next!=nullptr);
373 assert(last.prior!=nullptr);
374 if (empty()){
375 assert(first.next == &last);
376 assert(last.prior == &first);
377 }
378 }
379
380};
381
382}
#define assert(T)
Definition avr.h:10
Memory allocateator which uses malloc.
Definition Allocator.h:25
virtual void free(void *memory)
frees memory
Definition Allocator.h:84
virtual void * allocate(size_t size)
Allocates memory.
Definition Allocator.h:72
Definition List.h:27
bool operator!=(Iterator it)
Definition List.h:61
Iterator operator-(int offset)
Definition List.h:55
T & operator*()
Definition List.h:64
T * operator->()
Definition List.h:67
Node * get_node()
Definition List.h:70
bool is_eof
Definition List.h:78
Iterator(Node *node)
Definition List.h:29
Iterator operator--(int)
Definition List.h:49
Iterator operator+(int offset)
Definition List.h:52
Iterator operator--()
Definition List.h:42
Node * node
Definition List.h:77
Iterator operator++(int)
Definition List.h:39
Iterator operator++()
Definition List.h:32
bool operator==(Iterator it)
Definition List.h:58
Iterator getIteratorAtOffset(int offset)
Definition List.h:80
Double linked list.
Definition List.h:19
size_t record_count
Definition List.h:338
size_t size()
Definition List.h:294
List(Allocator &allocator=DefaultAllocator)
Default constructor.
Definition List.h:104
bool pop_front(T &data)
Definition List.h:212
Node * firstDataNode()
Definition List.h:367
Iterator begin()
Definition List.h:274
Node first
Definition List.h:336
Allocator * p_allocator
Definition List.h:339
bool insert(Iterator it, const T &data)
Definition List.h:182
Node last
Definition List.h:337
Node * lastDataNode()
Definition List.h:364
bool empty()
Definition List.h:298
bool pop_front()
Definition List.h:202
void validate()
Definition List.h:371
T & back()
Provides the last element.
Definition List.h:330
bool pop_back(T &data)
Definition List.h:233
~List()
Definition List.h:120
bool swap(List< T > &ref)
Definition List.h:132
Iterator rend()
Definition List.h:289
bool clear()
Definition List.h:302
void deleteNode(Node *p_delete)
Definition List.h:350
T & front()
Provides the first element.
Definition List.h:325
Iterator rbegin()
Definition List.h:284
Iterator end()
Definition List.h:279
T & operator[](int index)
Definition List.h:309
Node * createNode()
Definition List.h:341
bool pop_back()
Definition List.h:207
void setAllocator(Allocator &allocator)
Definition List.h:320
bool push_front(T data)
Definition List.h:165
bool erase(Iterator it)
Definition List.h:254
List(List &ref)=default
copy constructor
List(const T(&a)[N], Allocator &allocator=DefaultAllocator)
Constructor using array.
Definition List.h:113
void link()
Definition List.h:359
bool push_back(T data)
Definition List.h:148
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
static TAllocatorExt DefaultAllocator
Definition Allocator.h:208
Definition List.h:21
Node * next
Definition List.h:22
T data
Definition List.h:24
Node * prior
Definition List.h:23