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