]> jfr.im git - irc/gameservirc.git/blob - gameserv/list.h
Updated TODO and fixed the hashing algorithm for P10 numerics + others' nickname...
[irc/gameservirc.git] / gameserv / list.h
1 #ifndef LIST_H
2 #define LIST_H
3
4 #include <iostream>
5 #include <cassert>
6 #include "listnode.h"
7 #include "aClient.h"
8 #include "extern.h"
9 #include "options.h"
10
11 using std::cout;
12 using std::endl;
13 using std::flush;
14
15 template <class T>
16 class List {
17 public:
18 List(); //constructor
19 ~List(); //deconstructor
20 void insertAtFront( const T & );
21 void insertAtBack( T *&);
22 bool removeFromFront( T & );
23 bool removeFromBack( T & );
24 bool del( T *);
25 ListNode < T > *remove( T * );
26 bool isEmpty() const;
27 void print() const;
28 ListNode < T > *Find( T * );
29 ListNode < T > *First() { return firstPtr; };
30 ListNode < T > *Last() { return lastPtr; };
31 private:
32 ListNode < T > *firstPtr;
33 ListNode < T > *lastPtr;
34
35 ListNode < T > *getNewNode ( const T & );
36 };
37
38 template <class T>
39 List<T>::List() : firstPtr (0), lastPtr (0) {}
40
41 template <class T>
42 List<T>::~List()
43 {
44 if (!isEmpty())
45 {
46 #ifdef DEBUGMODE
47 log("Destroying Nodes");
48 #endif
49
50 ListNode<T> *currentPtr = firstPtr, *tempPtr;
51
52 while (currentPtr)
53 {
54 tempPtr = currentPtr;
55 currentPtr = currentPtr->Next();
56
57 #ifdef DEBUGMODE
58 log("Deleting Memory address: %s", tempPtr->getData());
59 #endif
60
61 delete tempPtr;
62 }
63 #ifdef DEBUGMODE
64 log("All Nodes destroyed");
65 #endif
66 }
67 }
68
69 template<class T>
70 void List<T>::insertAtFront( const T &value )
71 {
72 ListNode<T> *newPtr = getNewNode ( value );
73
74
75 if (isEmpty())
76 firstPtr = lastPtr = newPtr;
77 else
78 {
79 newPtr->Next = firstPtr;
80 firstPtr->prev = newPtr;
81 firstPtr = newPtr;
82 }
83 }
84
85 template<class T>
86 void List<T>::insertAtBack(T *&value )
87 {
88 ListNode<T> *newPtr = getNewNode(*value);
89
90 if (isEmpty())
91 {
92 firstPtr = lastPtr = newPtr;
93 }
94 else
95 {
96 newPtr->prev = lastPtr;
97 lastPtr->next = newPtr;
98 lastPtr = newPtr;
99 }
100 }
101
102
103 template <class T>
104 bool List<T>::removeFromFront( T &value )
105 {
106 if ( isEmpty())
107 return false;
108 else
109 {
110 ListNode<T> *tempPtr = firstPtr;
111
112 if ( firstPtr == lastPtr )
113 firstPtr = lastPtr = 0;
114 else
115 firstPtr = firstPtr->next;
116
117 value = tempPtr->getData();
118 delete tempPtr;
119 return true;
120 }
121 }
122
123 template <class T>
124 bool List<T>::removeFromBack( T &value )
125 {
126 if ( isEmpty() )
127 return false;
128 else
129 {
130 ListNode<T> *tempPtr = lastPtr;
131
132 if ( firstPtr == lastPtr )
133 lastPtr = firstPtr = 0;
134 else
135 lastPtr = lastPtr->prev;
136
137 value = tempPtr->getData();
138 delete tempPtr;
139 return true;
140
141 }
142 }
143
144 template <class T>
145 bool List<T>::isEmpty() const
146 { return firstPtr == 0 && lastPtr == 0; }
147
148 template <class T>
149 ListNode<T> *List<T>::getNewNode( const T &value)
150 {
151 ListNode<T> *ptr = new ListNode<T>(value);
152
153 assert( ptr != 0);
154
155 return ptr;
156 }
157 template<class T>
158 ListNode<T> *List<T>::Find( T *value )
159 {
160 if (isEmpty()) {return NULL;}
161
162 ListNode<T> *currentPtr;
163 currentPtr = firstPtr;
164 while (currentPtr)
165 {
166 if (currentPtr->getData() == value)
167 return currentPtr;
168 currentPtr = currentPtr->Next();
169 }
170 return NULL;
171 }
172
173 #ifdef DEBUGMODE
174 template <class T>
175 void List<T>::print() const
176 {
177 if (isEmpty())
178 {
179 cout << "Empty list" << endl;
180 return;
181 }
182
183 ListNode<T> *currentPtr;
184 currentPtr = firstPtr;
185 while (currentPtr)
186 {
187 cout << "aClient: " << *currentPtr->getData() << flush;
188
189 if (currentPtr->getData()->stats)
190 cout << " Player Name: " << currentPtr->getData()->stats->name
191 << " Password: " << currentPtr->getData()->stats->password << flush;
192 cout << endl;
193 currentPtr = currentPtr->next;
194 }
195 }
196 #endif
197
198 template <class T>
199 bool List<T>::del(T *remPtr)
200 {
201 ListNode<T> *removed = remove( remPtr );
202 if (removed != NULL)
203 {
204 delete removed;
205 return true;
206 }
207 return false;
208 }
209
210 template <class T>
211 ListNode<T> *List<T>::remove(T *remPtr)
212 {
213 ListNode<T> *newPtr = firstPtr;
214 T *testPtr;
215
216 if (isEmpty())
217 return false;
218
219 while (newPtr)
220 {
221 testPtr = newPtr->getData();
222 if (testPtr == remPtr)
223 {
224 if (firstPtr == lastPtr)
225 {
226 #ifdef DEBUGMODE
227 log("One Element. Deleting it");
228 #endif
229 firstPtr = lastPtr = NULL;
230 return newPtr;
231 }
232 else if (newPtr != lastPtr && newPtr != firstPtr)
233 {
234 #ifdef DEBUGMODE
235 log("Many elements, this one is in the middle. Deleting it, linking front to back, and back to front.");
236 #endif
237 newPtr->prev->next = newPtr->next;
238 newPtr->next->prev = newPtr->prev;
239 return newPtr;
240 }
241 else if (newPtr == lastPtr)
242 {
243 #ifdef DEBUGMODE
244 log("This was the last element. Deleting it, and pointing the tail to its previous element.");
245 #endif
246 lastPtr = newPtr->prev;
247 lastPtr->next = 0;
248 return newPtr;
249 }
250 else if (newPtr == firstPtr)
251 {
252 #ifdef DEBUGMODE
253 log("This was the first element. Deleting it, and pointing the head to its next element.");
254 #endif
255 firstPtr = newPtr->next;
256 firstPtr->prev = 0;
257 return newPtr;
258 }
259 }
260 newPtr = newPtr->next;
261 }
262 return NULL;
263 }
264 #endif