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 
36 template <typename T>
38 {
39  // static_assert(sizeof(T) <= 16, "List<T> should not be used with large
40  // objects");
41 
45  {
46  return m_Next;
47  }
51  {
52  return m_Previous;
53  }
54 
60  T value;
61 };
62 
63 template <class T, size_t nodePoolSize = 16>
65 {
68 
69  public:
71  typedef ::Iterator<T, node_t> Iterator;
73  typedef typename Iterator::Const ConstIterator;
78 
80  List();
83  List(const List &x);
85  ~List();
86 
89  List &operator=(const List &x);
90 
93  size_t size() const;
95  size_t count() const;
98  void pushBack(const T &value);
101  void pushBack(T &&value);
104  T popBack();
107  void pushFront(const T &value);
110  void pushFront(T &&value);
113  T popFront();
116  Iterator erase(Iterator &Iter);
119  ReverseIterator erase(ReverseIterator &Iter);
120 
123  inline Iterator begin()
124  {
125  return Iterator(m_First);
126  }
129  inline ConstIterator begin() const
130  {
131  return ConstIterator(m_First);
132  }
135  inline Iterator end()
136  {
137  return Iterator(0);
138  }
141  inline ConstIterator end() const
142  {
143  return ConstIterator(0);
144  }
147  inline ReverseIterator rbegin()
148  {
149  return ReverseIterator(m_Last);
150  }
153  inline ConstReverseIterator rbegin() const
154  {
155  return ConstReverseIterator(m_Last);
156  }
159  inline ReverseIterator rend()
160  {
161  return ReverseIterator(0);
162  }
165  inline ConstReverseIterator rend() const
166  {
167  return ConstReverseIterator(0);
168  }
169 
171  void clear();
174  void assign(const List &x);
175 
176  private:
178  size_t m_Count;
180  node_t *m_First;
182  node_t *m_Last;
183 
184  uint32_t m_Magic;
185 
189 };
190 
191 //
192 // List<T> implementation
193 //
194 
195 template <typename T, size_t nodePoolSize>
197  : m_Count(0), m_First(0), m_Last(0), m_Magic(0x1BADB002), m_NodePool()
198 {
199 }
200 
201 template <typename T, size_t nodePoolSize>
203  : m_Count(0), m_First(0), m_Last(0), m_Magic(0x1BADB002), m_NodePool()
204 {
205  assign(x);
206 }
207 template <typename T, size_t nodePoolSize>
209 {
210  assert(m_Magic == 0x1BADB002);
211  clear();
212 }
213 
214 template <typename T, size_t nodePoolSize>
216 {
217  assign(x);
218  return *this;
219 }
220 
221 template <typename T, size_t nodePoolSize>
223 {
224  return m_Count;
225 }
226 template <typename T, size_t nodePoolSize>
228 {
229  return m_Count;
230 }
231 template <typename T, size_t nodePoolSize>
233 {
234  node_t *newNode = m_NodePool.allocate();
235  newNode->m_Next = 0;
236  newNode->m_Previous = m_Last;
237  newNode->value = value;
238 
239  if (m_Last == 0)
240  m_First = newNode;
241  else
242  m_Last->m_Next = newNode;
243 
244  m_Last = newNode;
245  ++m_Count;
246 }
247 template <typename T, size_t nodePoolSize>
249 {
250  node_t *newNode = m_NodePool.allocate();
251  newNode->m_Next = 0;
252  newNode->m_Previous = m_Last;
253  newNode->value = pedigree_std::move(value);
254 
255  if (m_Last == 0)
256  m_First = newNode;
257  else
258  m_Last->m_Next = newNode;
259 
260  m_Last = newNode;
261  ++m_Count;
262 }
263 template <typename T, size_t nodePoolSize>
265 {
266  // Handle an extremely unusual case
267  if (!m_Last && !m_First)
268  return T();
269 
270  node_t *node = m_Last;
271  if (m_Last)
273  if (m_Last != 0)
274  m_Last->m_Next = 0;
275  else
276  m_First = 0;
277  --m_Count;
278 
279  if (!node)
280  return T();
281 
282  T value = node->value;
283  m_NodePool.deallocate(node);
284  return value;
285 }
286 template <typename T, size_t nodePoolSize>
288 {
289  node_t *newNode = m_NodePool.allocate();
290  newNode->m_Next = m_First;
291  newNode->m_Previous = 0;
292  newNode->value = value;
293 
294  if (m_First == 0)
295  m_Last = newNode;
296  else
297  m_First->m_Previous = newNode;
298 
299  m_First = newNode;
300  ++m_Count;
301 }
302 template <typename T, size_t nodePoolSize>
304 {
305  node_t *newNode = m_NodePool.allocate();
306  newNode->m_Next = m_First;
307  newNode->m_Previous = 0;
308  newNode->value = pedigree_std::move(value);
309 
310  if (m_First == 0)
311  m_Last = newNode;
312  else
313  m_First->m_Previous = newNode;
314 
315  m_First = newNode;
316  ++m_Count;
317 }
318 template <typename T, size_t nodePoolSize>
320 {
321  // Handle an extremely unusual case
322  if (!m_Last && !m_First)
323  return T();
324 
325  node_t *node = m_First;
326  if (m_First)
328  if (m_First != 0)
329  m_First->m_Previous = 0;
330  else
331  m_Last = 0;
332  --m_Count;
333 
334  if (!node)
335  return T();
336 
337  T value = node->value;
338  m_NodePool.deallocate(node);
339  return value;
340 }
341 template <typename T, size_t nodePoolSize>
344 {
345  node_t *Node = Iter.__getNode();
346  if (Node->m_Previous == 0)
347  m_First = Node->m_Next;
348  else
349  Node->m_Previous->m_Next = Node->m_Next;
350  if (Node->m_Next == 0)
351  m_Last = Node->m_Previous;
352  else
353  Node->m_Next->m_Previous = Node->m_Previous;
354  --m_Count;
355 
356  node_t *pNext = Node->m_Next;
357  // If pNext is NULL, this will be the same as 'end()'.
358  Iterator tmp(pNext);
359  delete Node;
360  return tmp;
361 }
362 
363 template <typename T, size_t nodePoolSize>
366 {
367  node_t *Node = Iter.__getNode();
368  if (Node->m_Next == 0)
369  m_First = Node->m_Previous;
370  else
371  Node->m_Next->m_Previous = Node->m_Previous;
372  if (Node->m_Previous == 0)
373  m_Last = Node->m_Next;
374  else
375  Node->m_Previous->m_Next = Node->m_Next;
376  --m_Count;
377 
378  node_t *pNext = Node->m_Previous;
379  // If pNext is NULL, this will be the same as 'rend()'.
380  ReverseIterator tmp(pNext);
381  delete Node;
382  return tmp;
383 }
384 
385 template <typename T, size_t nodePoolSize>
387 {
388  node_t *cur = m_First;
389  for (size_t i = 0; i < m_Count; i++)
390  {
391  node_t *tmp = cur;
392  cur = cur->m_Next;
393  delete tmp;
394  }
395 
396  m_Count = 0;
397  m_First = 0;
398  m_Last = 0;
399 }
400 template <typename T, size_t nodePoolSize>
402 {
403  if (m_Count != 0)
404  clear();
405 
406  ConstIterator Cur(x.begin());
407  ConstIterator End(x.end());
408  for (; Cur != End; ++Cur)
409  pushBack(*Cur);
410 }
411 
412 extern template class List<void *>; // IWYU pragma: keep
413 extern template class List<uint64_t>; // IWYU pragma: keep
414 extern template class List<uint32_t>; // IWYU pragma: keep
415 extern template class List<uint16_t>; // IWYU pragma: keep
416 extern template class List<uint8_t>; // IWYU pragma: keep
417 extern template class List<int64_t>; // IWYU pragma: keep
418 extern template class List<int32_t>; // IWYU pragma: keep
419 extern template class List<int16_t>; // IWYU pragma: keep
420 extern template class List<int8_t>; // IWYU pragma: keep
421 
424 #endif
void clear()
Definition: List.h:386
_ListNode_t * m_Previous
Definition: List.h:58
void pushBack(const T &value)
Definition: List.h:232
void assign(const List &x)
Definition: List.h:401
node_t * m_Last
Definition: List.h:182
Struct * __getNode()
Definition: Iterator.h:151
~List()
Definition: List.h:208
Iterator erase(Iterator &Iter)
Definition: List.h:343
size_t m_Count
Definition: List.h:178
ReverseIterator rend()
Definition: List.h:159
void pushFront(const T &value)
Definition: List.h:287
One node in the list.
Definition: List.h:37
size_t size() const
Definition: List.h:222
T popFront()
Definition: List.h:319
ReverseIterator rbegin()
Definition: List.h:147
_ListNode_t * previous()
Definition: List.h:50
List()
Definition: List.h:196
ConstIterator end() const
Definition: List.h:141
ConstIterator begin() const
Definition: List.h:129
Definition: List.h:64
ObjectPool< node_t, nodePoolSize > m_NodePool
Definition: List.h:188
Iterator::Const ConstIterator
Definition: List.h:73
T value
Definition: List.h:60
_ListNode_t< T > node_t
Definition: List.h:67
ConstReverseIterator rbegin() const
Definition: List.h:153
::Iterator< T, node_t > Iterator
Definition: List.h:71
#define assert(x)
Definition: assert.h:37
Iterator begin()
Definition: List.h:123
Iterator::ConstReverse ConstReverseIterator
Definition: List.h:77
ConstReverseIterator rend() const
Definition: List.h:165
Iterator::Reverse ReverseIterator
Definition: List.h:75
An iterator applicable for many data structures.
Definition: Iterator.h:43
node_t * m_First
Definition: List.h:180
_ListNode_t * next()
Definition: List.h:44
Iterator end()
Definition: List.h:135
_ListNode_t * m_Next
Definition: List.h:56
List & operator=(const List &x)
Definition: List.h:215
T popBack()
Definition: List.h:264
size_t count() const
Definition: List.h:227