All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
List.h
1 // Copyright eeGeo Ltd (2012-2014), All Rights Reserved
2 
3 #pragma once
4 
5 #include "Types.h"
6 
7 namespace Eegeo
8 {
9  template <typename T>
10  class ListItem
11  {
12  public:
13  ListItem ( T* pItem ) : m_pItem(pItem), m_prev(NULL), m_next(NULL)
14  {
15  }
16 
17  T* GetItem () { return m_pItem; }
18 
19  ListItem* GetPrev () { return m_prev; }
20  ListItem* GetNext () { return m_next; }
21 
22  void SetPrev ( ListItem* pPrev ) { m_prev = pPrev; }
23  void SetNext ( ListItem* pNext ) { m_next = pNext; }
24 
25 
26  private:
27 
28  T* m_pItem;
29 
30  ListItem* m_prev;
31  ListItem* m_next;
32  };
33 
34 
35  template <typename T>
36  class List
37  {
38  public:
39  List ();
40 
41  T* GetHead () { return m_head; }
42  T* GetTail () { return m_tail; }
43  u32 GetLength () { return m_length; }
44 
45  void AddToHead ( T* item );
46  void AddToTail ( T* item );
47 
48  void InsertBefore( T* item, T* listItem );
49  void InsertAfter ( T* item, T* listItem );
50 
51  T* RemoveHead ();
52  T* RemoveTail ();
53  T* Remove (T* item);
54 
55  private:
56  T* m_head;
57  T* m_tail;
58  u32 m_length;
59  };
60 
61  template <typename T>
62  List<T>::List() : m_head(NULL), m_tail(NULL), m_length(0)
63  {
64  }
65 
66  template <typename T>
67  void List<T>::AddToHead ( T* item )
68  {
69  item->SetPrev(NULL);
70  item->SetNext(m_head);
71 
72  if(m_head)
73  {
74  m_head->SetPrev(item);
75  }
76  else
77  {
78  m_tail = item;
79  }
80 
81  m_head = item;
82  m_length++;
83  }
84 
85  template <typename T>
86  void List<T>::AddToTail ( T* item )
87  {
88  item->SetPrev(m_tail);
89  item->SetNext(NULL);
90 
91  if(m_tail)
92  {
93  m_tail->SetNext(item);
94  }
95  else
96  {
97  m_head = item;
98  }
99 
100  m_tail = item;
101  m_length++;
102  }
103 
104  template <typename T>
105  void List<T>::InsertBefore( T* item, T* listItem )
106  {
107  item->SetPrev(listItem->GetPrev());
108  item->SetNext(listItem);
109 
110  if(listItem->GetPrev())
111  {
112  listItem->GetPrev()->SetNext(item);
113  }
114 
115  listItem->SetPrev(item);
116 
117  if(m_head == listItem)
118  {
119  m_head = item;
120  }
121 
122  m_length++;
123  }
124 
125  template <typename T>
126  void List<T>::InsertAfter ( T* item, T* listItem )
127  {
128  item->SetPrev(listItem);
129  item->SetNext(listItem->GetNext());
130 
131  if(listItem->GetNext())
132  {
133  listItem->GetNext()->SetPrev(item);
134  }
135 
136  listItem->SetNext(item);
137 
138  if(m_tail == listItem)
139  {
140  m_tail = item;
141  }
142 
143  m_length++;
144  }
145 
146  template <typename T>
147  T* List<T>::RemoveHead ()
148  {
149  T* head = m_head;
150 
151  if(m_head)
152  {
153  if(m_head->GetNext())
154  {
155  m_head->GetNext()->SetPrev(NULL);
156  }
157 
158  if(m_head == m_tail)
159  {
160  m_tail = NULL;
161  }
162 
163  m_head = m_head->GetNext();
164 
165  head->SetPrev(NULL);
166  head->SetNext(NULL);
167 
168  m_length--;
169  }
170 
171  return head;
172  }
173 
174  template <typename T>
175  T* List<T>::RemoveTail ()
176  {
177  T* tail = m_tail;
178 
179  if(m_tail)
180  {
181  if(m_tail->GetPrev())
182  {
183  m_tail->GetPrev()->SetNext(NULL);
184  }
185 
186  if(m_head == m_tail)
187  {
188  m_head = NULL;
189  }
190 
191  m_tail = m_tail->GetPrev();
192 
193  tail->SetPrev(NULL);
194  tail->SetNext(NULL);
195 
196  m_length--;
197  }
198 
199  return tail;
200  }
201 
202  template <typename T>
203  T* List<T>::Remove(T* item)
204  {
205  if(m_head == item)
206  {
207  return RemoveHead();
208  }
209  else if(m_tail == item)
210  {
211  return RemoveTail();
212  }
213  else
214  {
215  if(item->GetPrev())
216  {
217  item->GetPrev()->SetNext(item->GetNext());
218  }
219 
220  if(item->GetNext())
221  {
222  item->GetNext()->SetPrev(item->GetPrev());
223  }
224 
225  item->SetPrev(NULL);
226  item->SetNext(NULL);
227 
228  m_length--;
229 
230  return item;
231  }
232  }
233 }