Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
SList.h
1/* Renegade Scripts.dll
2 Copyright 2013 Tiberian Technologies
3
4 This file is part of the Renegade scripts.dll
5 The Renegade scripts.dll is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version. See the file COPYING for more details.
9 In addition, an exemption is given to allow Run Time Dynamic Linking of this code with any closed source module that does not contain code covered by this licence.
10 Only the source code to the module(s) containing the licenced code has to be released.
11*/
12#ifndef TT_INCLUDE__SLIST_H
13#define TT_INCLUDE__SLIST_H
14
15
16
17#include "engine_vector.h"
18
19
20
21class GenericSLNode :
22 public AutoPoolClass<GenericSLNode, 256>
23{
24
25protected:
26
27 void Internal_Set_Next(void *n)
28 {
29 NodeNext = n;
30 }
31 void Internal_Set_Data(void *d)
32 {
33 NodeData = d;
34 }
35 void* NodeNext; // 0
36 void* NodeData; // 4
37 GenericSLNode(void *obj)
38 {
39 NodeData = obj;
40 NodeNext = NULL;
41 }
42 GenericSLNode(void* data, GenericSLNode* next)
43 {
44 NodeData = data;
45 NodeNext = next;
46 }
47};
48
49template<class T> class SList;
50template<class T>
51class SLNode : public GenericSLNode
52{
53public:
54
55 friend class SList<T>;
56 void Set_Next(SLNode<T>* n)
57 {
58 NodeNext = n;
59 }
60 SLNode<T> *Next() const
61 {
62 return (SLNode<T>*)NodeNext;
63 }
64 T* Data() const
65 {
66 return (T*)NodeData;
67 }
68protected:
69 SLNode(T *obj) : GenericSLNode(obj) {}
70 SLNode(T* data, SLNode<T>* next) : GenericSLNode(data, next) {}
71private:
72 SLNode() {}
73};
74
75
76
77template<class T>
78class SList
79{
80private:
81 SLNode<T>* HeadNode;
82 SLNode<T>* TailNode;
83public:
84 SList() :
85 HeadNode(0), TailNode(0)
86 {
87 }
88
89 virtual ~SList()
90 {
91 Remove_All();
92 }
93
94
95 virtual bool Add_Head(T* data)
96 {
97 if (!data)
98 {
99 return false;
100 }
101 SLNode<T> *temp = new SLNode<T>(data);
102 temp->Set_Next(HeadNode);
103 HeadNode = temp;
104 if (!TailNode)
105 {
106 TailNode = temp;
107 }
108 return true;
109 }
110
111
112 virtual bool Add_Head(SList<T>& list)
113 {
114 if (list.HeadNode == NULL)
115 {
116 return false;
117 }
118 SLNode<T> *addpoint = NULL;
119 for (SLNode<T> *cur = list.HeadNode; cur; cur = cur->Next())
120 {
121 if (addpoint)
122 {
123 SLNode<T> *temp = new SLNode<T>(cur->Data());
124 temp->Set_Next(addpoint->Next());
125 addpoint->Set_Next(temp);
126 addpoint = temp;
127 }
128 else
129 {
130 Add_Head(cur->Data());
131 addpoint = HeadNode;
132 }
133 }
134 return true;
135 }
136
137
138 virtual bool Add_Tail(T* data)
139 {
140 if (data == NULL)
141 {
142 return false;
143 }
144 SLNode<T> *temp = new SLNode<T> (data);
145 if (HeadNode == NULL)
146 {
147 HeadNode = TailNode = temp;
148 }
149 else
150 {
151 TailNode->Set_Next(temp);
152 TailNode = temp;
153 }
154 return true;
155 }
156
157
158 virtual bool Add_Tail(SList<T>& list)
159 {
160 if (list.HeadNode == NULL)
161 {
162 return false;
163 }
164 for (SLNode<T> *cur = list.HeadNode; cur; cur = cur->Next())
165 {
166 Add_Tail(cur->Data());
167 }
168 return true;
169 }
170
171
172 virtual T* Remove_Head()
173 {
174 if (HeadNode == NULL)
175 {
176 return ((T* )NULL);
177 }
178 SLNode<T> *temp = HeadNode;
179 HeadNode = HeadNode->Next();
180 if (HeadNode == NULL)
181 {
182 TailNode = NULL;
183 }
184 T *data = temp->Data();
185 delete temp;
186 return data;
187 }
188
189
190 virtual T* Remove_Tail()
191 {
192 if (HeadNode == NULL)
193 {
194 return ((T *)NULL);
195 }
196 T* data = TailNode->Data();
197 return (Remove(data) ? data : (T*)NULL);
198 }
199
200
201 virtual bool Remove(const T* element)
202 {
203 if (element == NULL || HeadNode == NULL)
204 {
205 return false;
206 }
207 if (HeadNode->Data() == element)
208 {
209 return Remove_Head() != NULL ? true : false;
210 }
211 SLNode<T> *cur;
212 for (cur = HeadNode; cur->Next() && cur->Next()->Data() != element; cur=cur->Next())
213 {
214 }
215 if (cur->Next() != NULL && cur->Next()->Data() == element)
216 {
217 SLNode<T> *temp = cur->Next();
218 cur->Set_Next(temp->Next());
219 if (temp == TailNode)
220 {
221 TailNode = cur;
222 }
223 delete temp;
224 return true;
225 }
226 return false;
227 }
228
229
230 virtual void Remove_All()
231 {
232 SLNode<T> *next;
233 for (SLNode<T> *cur = HeadNode; cur; cur = next)
234 {
235 next = cur->Next();
236 delete cur;
237 }
238 HeadNode = TailNode = NULL;
239 }
240
241
242 virtual bool Insert_Before(T* newnode, const T* oldnode)
243 {
244 if (newnode == NULL)
245 {
246 return false;
247 }
248 if (oldnode == NULL || HeadNode == NULL || HeadNode->Data() == oldnode)
249 {
250 return Add_Head(newnode);
251 }
252 SLNode<T> *cur;
253 for (cur=HeadNode; cur->Next() && cur->Next()->Data() != oldnode; cur=cur->Next())
254 {
255 }
256 if (cur->Next() != NULL && cur->Next()->Data() == oldnode)
257 {
258 SLNode<T> *temp = new SLNode<T> (newnode);
259 temp->Set_Next(cur->Next());
260 cur->Set_Next(temp);
261 return true;
262 }
263 return false;
264 }
265
266 virtual bool Insert_After(T* newnode, const T* oldnode)
267 {
268 if (newnode == NULL)
269 {
270 return false;
271 }
272 if (oldnode == NULL || HeadNode == NULL)
273 {
274 return(Add_Head(newnode));
275 }
276 SLNode<T> *cur;
277 for (cur = HeadNode; cur && cur->Data() != oldnode; cur = cur->Next())
278 {
279 }
280 if (cur != NULL && cur->Data() == oldnode)
281 {
282 if (cur == TailNode)
283 {
284 return(Add_Tail(newnode));
285 }
286 SLNode<T> *temp = new SLNode<T>(newnode);
287 temp->Set_Next(cur->Next());
288 cur->Set_Next(temp);
289 return true;
290 }
291 return false;
292 }
293
294
295 virtual bool Is_Empty() const
296 {
297 return !HeadNode;
298 }
299
300
301 virtual uint32 Get_Count() const
302 {
303 uint32 count = 0;
304
305 for (SLNode<T>* node = HeadNode; node; node = node->Next())
306 ++count;
307
308 return count;
309 }
310
311
312 SLNode<T>* Head() const
313 {
314 return HeadNode;
315 }
316
317 SLNode<T>* Tail() const
318 {
319 return TailNode;
320 }
321
322 SLNode<T> *Find_Node(T * data) const
323 {
324 SLNode<T> * cur;
325 for (cur = HeadNode;cur && cur->Data() != data;cur = cur->Next())
326 {
327 }
328 return cur;
329 }
330
331 void insertBefore(T* data, SLNode<T>& node)
332 {
333 // Instead of adding before (which we can't), move the current data to the next node and replace the current node.
334 SLNode<T>* nextNode = new SLNode<T>(node.Data(), node.Next());
335 node.NodeNext = nextNode;
336 node.NodeData = data;
337 if (&node == TailNode)
338 TailNode = nextNode;
339 }
340
341 void insertAfter(T* data, SLNode<T>& node)
342 {
343 SLNode<T>* nextNode = new SLNode<T>(data, node.Next());
344 node.NodeNext = nextNode;
345 if (&node == TailNode)
346 TailNode = nextNode;
347 }
348
349}; // 000C
350
351template <typename T>
352class SLIterator
353{
354public:
355 SLIterator(SList<T>& list): Node(list.Head()) { };
356
357 bool IsDone() const { return !Node->Next(); }
358 T* operator ->() { return Node->Data(); }
359 T* operator * () { return Node->Data(); }
360 SLIterator<T>& operator ++ () { Node = Node->Next(); }
361
362private:
363 SLNode<T>* Node;
364};
365
366#endif