]> jfr.im git - irc/gameservirc.git/blame - gameserv/list.h
Shrunk the dependencies immensely with forward declarations in all H files instead...
[irc/gameservirc.git] / gameserv / list.h
CommitLineData
85ce9d3e 1#ifndef LIST_H
2#define LIST_H
3
fb37ecc7 4#include <iostream>
85ce9d3e 5#include <cassert>
6#include "listnode.h"
7#include "aClient.h"
fc9d2643 8#include "options.h"
9d057db5 9
fb37ecc7 10using std::cout;
11using std::endl;
fc9d2643 12using std::flush;
fb37ecc7 13
5c449fde 14extern void log(const char *fmt, ...);
183a166f 15
85ce9d3e 16template <class T>
17class List {
18 public:
19 List(); //constructor
20 ~List(); //deconstructor
448a1531 21 T *insertAtFront( const T & );
22 T *insertAtBack( T *&);
bf3a2ff9 23 T *random(); // Returns a random element in the list
ae2685f6 24 ListNode<T> *insertAtBack_RLN( T *&);
85ce9d3e 25 bool removeFromFront( T & );
26 bool removeFromBack( T & );
59dc3990 27 bool del( T *);
28 ListNode < T > *remove( T * );
85ce9d3e 29 bool isEmpty() const;
c260a8d7 30 #ifdef DEBUGMODE
85ce9d3e 31 void print() const;
c260a8d7 32 #endif
5aa1d28d 33 void deleteNodes();
c260a8d7 34
1cf88153 35 ListNode < T > *Find( T * );
85ce9d3e 36 ListNode < T > *First() { return firstPtr; };
37 ListNode < T > *Last() { return lastPtr; };
bf3a2ff9 38 int elements; // Number of elements in the list
85ce9d3e 39 private:
40 ListNode < T > *firstPtr;
41 ListNode < T > *lastPtr;
42
43 ListNode < T > *getNewNode ( const T & );
bf3a2ff9 44 ListNode < T > *getNewNode ( T & );
85ce9d3e 45};
46
47template <class T>
bf3a2ff9 48List<T>::List() : firstPtr (0), lastPtr (0) {elements = 0;}
85ce9d3e 49
50template <class T>
5aa1d28d 51void List<T>::deleteNodes()
85ce9d3e 52{
5aa1d28d 53 if (isEmpty())
54 return;
55 ListNode<T> *it = firstPtr, *tempPtr;
56 while (it)
85ce9d3e 57 {
5aa1d28d 58 tempPtr = it;
59 it = it->Next();
60 delete tempPtr;
85ce9d3e 61 }
3c13eb61 62 firstPtr = NULL;
63 lastPtr = NULL;
bf3a2ff9 64 elements = 0;
85ce9d3e 65}
66
5aa1d28d 67template <class T>
68List<T>::~List()
69{
70 deleteNodes();
71}
72
bf3a2ff9 73template<class T>
74T *List<T>::random()
75{
76 if (isEmpty())
77 return NULL;
78
79 int num = rand() % elements;
80 ListNode<T> *it = firstPtr;
81 for (int x = 0; x < num; x++)
82 {
83 it = it->Next();
84 }
85 return it->getData();
86}
87
85ce9d3e 88template<class T>
448a1531 89T *List<T>::insertAtFront( const T &value )
85ce9d3e 90{
91 ListNode<T> *newPtr = getNewNode ( value );
92
93
94 if (isEmpty())
95 firstPtr = lastPtr = newPtr;
96 else
97 {
98 newPtr->Next = firstPtr;
99 firstPtr->prev = newPtr;
100 firstPtr = newPtr;
101 }
bf3a2ff9 102 elements++;
448a1531 103 return firstPtr->getData();
85ce9d3e 104}
105
106template<class T>
448a1531 107T *List<T>::insertAtBack(T *&value )
85ce9d3e 108{
109 ListNode<T> *newPtr = getNewNode(*value);
110
111 if (isEmpty())
112 {
113 firstPtr = lastPtr = newPtr;
114 }
115 else
116 {
117 newPtr->prev = lastPtr;
118 lastPtr->next = newPtr;
119 lastPtr = newPtr;
120 }
bf3a2ff9 121 elements++;
448a1531 122 return lastPtr->getData();
85ce9d3e 123}
124
ae2685f6 125template<class T>
126ListNode<T> *List<T>::insertAtBack_RLN(T *&value )
127{
128 ListNode<T> *newPtr = getNewNode(*value);
129
130 if (isEmpty())
131 {
132 firstPtr = lastPtr = newPtr;
133 }
134 else
135 {
136 newPtr->prev = lastPtr;
137 lastPtr->next = newPtr;
138 lastPtr = newPtr;
139 }
bf3a2ff9 140 elements++;
ae2685f6 141 return lastPtr;
142}
143
85ce9d3e 144
145template <class T>
146bool List<T>::removeFromFront( T &value )
147{
148 if ( isEmpty())
149 return false;
150 else
151 {
152 ListNode<T> *tempPtr = firstPtr;
153
154 if ( firstPtr == lastPtr )
155 firstPtr = lastPtr = 0;
156 else
157 firstPtr = firstPtr->next;
158
159 value = tempPtr->getData();
160 delete tempPtr;
bf3a2ff9 161 elements--;
85ce9d3e 162 return true;
163 }
164}
165
166template <class T>
167bool List<T>::removeFromBack( T &value )
168{
169 if ( isEmpty() )
170 return false;
171 else
172 {
173 ListNode<T> *tempPtr = lastPtr;
174
175 if ( firstPtr == lastPtr )
176 lastPtr = firstPtr = 0;
177 else
178 lastPtr = lastPtr->prev;
179
180 value = tempPtr->getData();
181 delete tempPtr;
bf3a2ff9 182 elements--;
85ce9d3e 183 return true;
85ce9d3e 184 }
185}
186
187template <class T>
188bool List<T>::isEmpty() const
0a1518fa 189 { return firstPtr == 0 && lastPtr == 0; }
85ce9d3e 190
191template <class T>
192ListNode<T> *List<T>::getNewNode( const T &value)
193{
194 ListNode<T> *ptr = new ListNode<T>(value);
195
196 assert( ptr != 0);
197
198 return ptr;
199}
bf3a2ff9 200
201template <class T>
202ListNode<T> *List<T>::getNewNode( T &value)
203{
204 ListNode<T> *ptr = new ListNode<T>(value);
205
206 assert( ptr != 0);
207
208 return ptr;
209}
210
1cf88153 211template<class T>
212ListNode<T> *List<T>::Find( T *value )
213{
214 if (isEmpty()) {return NULL;}
215
216 ListNode<T> *currentPtr;
217 currentPtr = firstPtr;
218 while (currentPtr)
219 {
ae2685f6 220 cout << currentPtr->getData() << endl << value << endl;
1cf88153 221 if (currentPtr->getData() == value)
222 return currentPtr;
223 currentPtr = currentPtr->Next();
224 }
225 return NULL;
226}
85ce9d3e 227
9f8c2acc 228#ifdef DEBUGMODE
85ce9d3e 229template <class T>
230void List<T>::print() const
231{
232 if (isEmpty())
233 {
234 cout << "Empty list" << endl;
235 return;
236 }
237
238 ListNode<T> *currentPtr;
239 currentPtr = firstPtr;
240 while (currentPtr)
241 {
87137def 242 /*
cdc9a6db 243 cout << "aClient: " << *currentPtr->getData() << flush;
85ce9d3e 244
245 if (currentPtr->getData()->stats)
cdc9a6db 246 cout << " Player Name: " << currentPtr->getData()->stats->name
247 << " Password: " << currentPtr->getData()->stats->password << flush;
85ce9d3e 248 cout << endl;
87137def 249 */
bf3a2ff9 250 /*
87137def 251 cout << currentPtr->getData()->getString() << endl;
85ce9d3e 252 currentPtr = currentPtr->next;
bf3a2ff9 253 */
37ed80a9 254 /*
bf3a2ff9 255 T *dat;
256 dat = currentPtr->getData();
5c449fde 257 log("name: %s", dat->name.c_str());
258 log("weapon: %s", dat->weapon.c_str());
259 log("death: %s", dat->death.c_str());
bf3a2ff9 260 log("strength: %d", dat->strength);
261 log("exp: %ld", dat->exp);
262 log("gold: %ld", dat->gold);
263 log("maxhp: %d", dat->maxhp);
264 log("hp: %d", dat->hp);
265 currentPtr = currentPtr->next;
37ed80a9 266 */
85ce9d3e 267 }
85ce9d3e 268}
9f8c2acc 269#endif
85ce9d3e 270
271template <class T>
59dc3990 272bool List<T>::del(T *remPtr)
273{
274 ListNode<T> *removed = remove( remPtr );
275 if (removed != NULL)
276 {
277 delete removed;
278 return true;
279 }
280 return false;
281}
282
283template <class T>
284ListNode<T> *List<T>::remove(T *remPtr)
85ce9d3e 285{
286 ListNode<T> *newPtr = firstPtr;
287 T *testPtr;
288
0a1518fa 289 if (isEmpty())
290 return false;
291
85ce9d3e 292 while (newPtr)
293 {
294 testPtr = newPtr->getData();
295 if (testPtr == remPtr)
296 {
297 if (firstPtr == lastPtr)
298 {
9f8c2acc 299 #ifdef DEBUGMODE
300 log("One Element. Deleting it");
301 #endif
0a1518fa 302 firstPtr = lastPtr = NULL;
59dc3990 303 return newPtr;
85ce9d3e 304 }
305 else if (newPtr != lastPtr && newPtr != firstPtr)
306 {
9f8c2acc 307 #ifdef DEBUGMODE
308 log("Many elements, this one is in the middle. Deleting it, linking front to back, and back to front.");
309 #endif
85ce9d3e 310 newPtr->prev->next = newPtr->next;
311 newPtr->next->prev = newPtr->prev;
59dc3990 312 return newPtr;
85ce9d3e 313 }
314 else if (newPtr == lastPtr)
315 {
9f8c2acc 316 #ifdef DEBUGMODE
317 log("This was the last element. Deleting it, and pointing the tail to its previous element.");
318 #endif
85ce9d3e 319 lastPtr = newPtr->prev;
320 lastPtr->next = 0;
59dc3990 321 return newPtr;
85ce9d3e 322 }
323 else if (newPtr == firstPtr)
324 {
9f8c2acc 325 #ifdef DEBUGMODE
326 log("This was the first element. Deleting it, and pointing the head to its next element.");
327 #endif
85ce9d3e 328 firstPtr = newPtr->next;
329 firstPtr->prev = 0;
59dc3990 330 return newPtr;
85ce9d3e 331 }
bf3a2ff9 332 elements--;
85ce9d3e 333 }
334 newPtr = newPtr->next;
335 }
59dc3990 336 return NULL;
85ce9d3e 337}
338#endif