The Pedigree Project 0.1
List.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef KERNEL_UTILITIES_LIST_H
21#define KERNEL_UTILITIES_LIST_H
22
23#include "pedigree/kernel/compiler.h"
24#include "pedigree/kernel/processor/types.h"
25#include "pedigree/kernel/utilities/Iterator.h"
26#include "pedigree/kernel/utilities/ObjectPool.h"
27#include "pedigree/kernel/utilities/assert.h"
28#include "pedigree/kernel/utilities/utility.h"
29
36template <typename T>
38 // static_assert(sizeof(T) <= 16, "List<T> should not be used with large
39 // objects");
40
44 return m_Next;
45 }
49 return m_Previous;
50 }
51
58};
59
60template <class T, size_t nodePoolSize = 16>
61class EXPORTED_PUBLIC List {
64
65 public:
67 typedef ::Iterator<T, node_t> Iterator;
74
79 List(const List& x);
82
85 List& operator=(const List& x);
86
89 size_t size() const;
91 size_t count() const;
94 void pushBack(const T& value);
97 void pushBack(T&& value);
99 bool tryPushBack(const T& value);
100 bool tryPushBack(T&& value);
106 void pushFront(const T& value);
109 void pushFront(T&& value);
119
122 inline Iterator begin() {
123 return Iterator(m_First);
124 }
127 inline ConstIterator begin() const {
128 return ConstIterator(m_First);
129 }
132 inline Iterator end() {
133 return Iterator(0);
134 }
137 inline ConstIterator end() const {
138 return ConstIterator(0);
139 }
143 return ReverseIterator(m_Last);
144 }
148 return ConstReverseIterator(m_Last);
149 }
153 return ReverseIterator(0);
154 }
157 inline ConstReverseIterator rend() const {
158 return ConstReverseIterator(0);
159 }
160
162 void clear();
165 void assign(const List& x);
166
167 private:
169 size_t m_Count;
174
175 uint32_t m_Magic;
176
180};
181
182//
183// List<T> implementation
184//
185
186template <typename T, size_t nodePoolSize>
188 : m_Count(0), m_First(0), m_Last(0), m_Magic(0x1BADB002), m_NodePool() {}
189
190template <typename T, size_t nodePoolSize>
192 : m_Count(0), m_First(0), m_Last(0), m_Magic(0x1BADB002), m_NodePool() {
193 assign(x);
194}
195template <typename T, size_t nodePoolSize>
197 assert(m_Magic == 0x1BADB002);
198 clear();
199}
200
201template <typename T, size_t nodePoolSize>
203 assign(x);
204 return *this;
205}
206
207template <typename T, size_t nodePoolSize>
209 return m_Count;
210}
211template <typename T, size_t nodePoolSize>
213 return m_Count;
214}
215template <typename T, size_t nodePoolSize>
217 node_t* newNode = m_NodePool.allocate();
218 newNode->m_Next = 0;
219 newNode->m_Previous = m_Last;
220 newNode->value = value;
221
222 if (m_Last == 0)
223 m_First = newNode;
224 else
225 m_Last->m_Next = newNode;
226
227 m_Last = newNode;
228 ++m_Count;
229}
230template <typename T, size_t nodePoolSize>
232 node_t* newNode = m_NodePool.allocate();
233 newNode->m_Next = 0;
234 newNode->m_Previous = m_Last;
235 newNode->value = pedigree_std::move(value);
236
237 if (m_Last == 0)
238 m_First = newNode;
239 else
240 m_Last->m_Next = newNode;
241
242 m_Last = newNode;
243 ++m_Count;
244}
245template <typename T, size_t nodePoolSize>
247 node_t* newNode = m_NodePool.tryAllocate();
248 if (!newNode)
249 return false;
250 newNode->m_Next = nullptr;
251 newNode->m_Previous = m_Last;
252 newNode->value = value;
253 if (m_Last)
254 m_Last->m_Next = newNode;
255 else
256 m_First = newNode;
257 m_Last = newNode;
258 ++m_Count;
259 return true;
260}
261template <typename T, size_t nodePoolSize>
263 node_t* newNode = m_NodePool.tryAllocate();
264 if (!newNode)
265 return false;
266 newNode->m_Next = nullptr;
267 newNode->m_Previous = m_Last;
268 newNode->value = pedigree_std::move(value);
269 if (m_Last)
270 m_Last->m_Next = newNode;
271 else
272 m_First = newNode;
273 m_Last = newNode;
274 ++m_Count;
275 return true;
276}
277template <typename T, size_t nodePoolSize>
279 // Handle an extremely unusual case
280 if (!m_Last && !m_First)
281 return T();
282
283 node_t* node = m_Last;
284 if (m_Last)
285 m_Last = m_Last->m_Previous;
286 if (m_Last != 0)
287 m_Last->m_Next = 0;
288 else
289 m_First = 0;
290 --m_Count;
291
292 if (!node)
293 return T();
294
295 T value = node->value;
296 m_NodePool.deallocate(node);
297 return value;
298}
299template <typename T, size_t nodePoolSize>
301 node_t* newNode = m_NodePool.allocate();
302 newNode->m_Next = m_First;
303 newNode->m_Previous = 0;
304 newNode->value = value;
305
306 if (m_First == 0)
307 m_Last = newNode;
308 else
309 m_First->m_Previous = newNode;
310
311 m_First = newNode;
312 ++m_Count;
313}
314template <typename T, size_t nodePoolSize>
316 node_t* newNode = m_NodePool.allocate();
317 newNode->m_Next = m_First;
318 newNode->m_Previous = 0;
319 newNode->value = pedigree_std::move(value);
320
321 if (m_First == 0)
322 m_Last = newNode;
323 else
324 m_First->m_Previous = newNode;
325
326 m_First = newNode;
327 ++m_Count;
328}
329template <typename T, size_t nodePoolSize>
331 // Handle an extremely unusual case
332 if (!m_Last && !m_First)
333 return T();
334
335 node_t* node = m_First;
336 if (m_First)
337 m_First = m_First->m_Next;
338 if (m_First != 0)
339 m_First->m_Previous = 0;
340 else
341 m_Last = 0;
342 --m_Count;
343
344 if (!node)
345 return T();
346
347 T value = node->value;
348 m_NodePool.deallocate(node);
349 return value;
350}
351template <typename T, size_t nodePoolSize>
353 node_t* Node = Iter.__getNode();
354 if (!Node)
355 return end();
356
357 if (Node->m_Previous == 0)
358 m_First = Node->m_Next;
359 else
360 Node->m_Previous->m_Next = Node->m_Next;
361 if (Node->m_Next == 0)
362 m_Last = Node->m_Previous;
363 else
364 Node->m_Next->m_Previous = Node->m_Previous;
365 --m_Count;
366
367 node_t* pNext = Node->m_Next;
368 // If pNext is NULL, this will be the same as 'end()'.
369 Iterator tmp(pNext);
370 m_NodePool.deallocate(Node);
371 return tmp;
372}
373
374template <typename T, size_t nodePoolSize>
376 ReverseIterator& Iter) {
377 node_t* Node = Iter.__getNode();
378 if (!Node)
379 return rend();
380
381 if (Node->m_Previous == 0)
382 m_First = Node->m_Next;
383 else
384 Node->m_Previous->m_Next = Node->m_Next;
385 if (Node->m_Next == 0)
386 m_Last = Node->m_Previous;
387 else
388 Node->m_Next->m_Previous = Node->m_Previous;
389 --m_Count;
390
391 node_t* pNext = Node->m_Previous;
392 // If pNext is NULL, this will be the same as 'rend()'.
393 ReverseIterator tmp(pNext);
394 m_NodePool.deallocate(Node);
395 return tmp;
396}
397
398template <typename T, size_t nodePoolSize>
400 node_t* cur = m_First;
401 for (size_t i = 0; i < m_Count; i++) {
402 node_t* tmp = cur;
403 cur = cur->m_Next;
404 m_NodePool.deallocate(tmp);
405 }
406
407 m_Count = 0;
408 m_First = 0;
409 m_Last = 0;
410}
411template <typename T, size_t nodePoolSize>
413 if (this == &x)
414 return;
415
416 if (m_Count != 0)
417 clear();
418
419 ConstIterator Cur(x.begin());
420 ConstIterator End(x.end());
421 for (; Cur != End; ++Cur)
422 pushBack(*Cur);
423}
424
425extern template class List<void*>; // IWYU pragma: keep
426extern template class List<uint64_t>; // IWYU pragma: keep
427extern template class List<uint32_t>; // IWYU pragma: keep
428extern template class List<uint16_t>; // IWYU pragma: keep
429extern template class List<uint8_t>; // IWYU pragma: keep
430extern template class List<int64_t>; // IWYU pragma: keep
431extern template class List<int32_t>; // IWYU pragma: keep
432extern template class List<int16_t>; // IWYU pragma: keep
433extern template class List<int8_t>; // IWYU pragma: keep
434
437#endif
An iterator applicable for many data structures.
Definition Iterator.h:41
Struct * __getNode()
Definition Iterator.h:121
Definition List.h:61
Iterator begin()
Definition List.h:122
ReverseIterator rend()
Definition List.h:152
size_t m_Count
Definition List.h:169
ObjectPool< node_t, nodePoolSize > m_NodePool
Definition List.h:179
ReverseIterator rbegin()
Definition List.h:142
Iterator::ConstReverse ConstReverseIterator
Definition List.h:73
ConstIterator begin() const
Definition List.h:127
Iterator::Reverse ReverseIterator
Definition List.h:71
node_t * m_Last
Definition List.h:173
ConstReverseIterator rend() const
Definition List.h:157
Iterator::Const ConstIterator
Definition List.h:69
ConstReverseIterator rbegin() const
Definition List.h:147
_ListNode_t< T > node_t
Definition List.h:63
ConstIterator end() const
Definition List.h:137
::Iterator< T, node_t > Iterator
Definition List.h:67
node_t * m_First
Definition List.h:171
Iterator end()
Definition List.h:132
Iterator erase(Iterator &Iter)
Definition List.h:352
T popFront()
Definition List.h:330
void clear()
Definition List.h:399
ReverseIterator erase(ReverseIterator &Iter)
Definition List.h:375
bool tryPushBack(const T &value)
Definition List.h:246
void pushFront(const T &value)
Definition List.h:300
void pushBack(T &&value)
Definition List.h:231
size_t count() const
Definition List.h:212
List(const List &x)
Definition List.h:191
List()
Definition List.h:187
void pushBack(const T &value)
Definition List.h:216
size_t size() const
Definition List.h:208
List & operator=(const List &x)
Definition List.h:202
void pushFront(T &&value)
Definition List.h:315
T popBack()
Definition List.h:278
~List()
Definition List.h:196
void assign(const List &x)
Definition List.h:412
One node in the list.
Definition List.h:37
_ListNode_t * previous()
Definition List.h:48
T value
Definition List.h:57
_ListNode_t * next()
Definition List.h:43
_ListNode_t * m_Next
Definition List.h:53
_ListNode_t * m_Previous
Definition List.h:55