TORCS  1.3.9
The Open Racing Car Simulator
List.cpp
Go to the documentation of this file.
1 /* -*- Mode: C++; -*- */
2 /* VER: $Id$ */
3 // copyright (c) 2004 by Christos Dimitrakakis <dimitrak@idiap.ch>
4 /***************************************************************************
5  * *
6  * This program is free software; you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License as published by *
8  * the Free Software Foundation; either version 2 of the License, or *
9  * (at your option) any later version. *
10  * *
11  ***************************************************************************/
12 
13 #include <learning/List.h>
14 #include <learning/learn_debug.h>
15 
16 LIST* List(void)
17 {
18  LIST* list = NULL;
19 
20  if ((list = (LIST*) malloc(sizeof(LIST)))==NULL) {
21  Serror("Failed to create list structure\n");
22  return NULL;
23  }
24 
25  list->head = NULL;
26  list->tail = NULL;
27  list->curr = NULL;
28  list->n = 0;
30 
31  return list;
32 }
33 
34 LISTITEM* ListAppend(LIST* list, void* p) {
35  return ListAppend (list, p, NULL);
36 }
37 
38 LISTITEM* ListAppend(LIST* list, void* p, void (*free_obj) (void* obj))
39 {
40  LISTITEM* tmp = NULL;
41  assert(list);
42 
43  if (!p) {
44  Swarning("NULL pointer given for new list item data\n");
45  }
46 
47  if (!list->head) {
48  tmp = ListItem(p, free_obj);
49  list->head = tmp;
50  list->curr = tmp;
51  } else {
52  tmp = LinkNext(list->tail, p, free_obj);
53  }
54 
55  list->tail = tmp;
56 
57  list->n++;
58 
59  assert(list->head);
60  assert(list->curr);
61  assert(list->tail);
62 
63  return tmp;
64 }
65 
66 
68 {
69  LISTITEM* t;
70  assert(list);
71 
72  if (!list->curr)
73  return NULL;
74 
75  t = GetNextItem(list->curr);
76  if (t)
77  list->curr =t;
78  return t;
79 }
80 
82 {
83  LISTITEM* t;
84  assert(list);
85 
86  t = list->head;
87 
88  if (!t) {
89  // Swarning("No First Item\n");
90  return NULL;
91  }
92 
93  list->curr = t;
94  return t;
95 }
96 
97 
99 {
100  LISTITEM* t;
101  assert(list);
102 
103  t = list->tail;
104 
105  if (!t) {
106  // Swarning("No Last Item\n");
107  return NULL;
108  }
109 
110  list->curr = t;
111  return t;
112 }
113 
114 
116 {
117  if (ptr)
118  return ptr->next;
119  else {
120  Serror("Null pointer given to GetNextItem()\n");
121  return NULL;
122  }
123 
124 }
125 
127 {
128  if (ptr)
129  return ptr->prev;
130  else {
131  Serror("Null pointer given to GetPrevItem()\n");
132  return NULL;
133  }
134 }
135 
136 LISTITEM* LinkNext(LISTITEM* src, void* ptr, void (*free_obj) (void* obj))
137 {
138  LISTITEM* tmp;
139  LISTITEM* dst = NULL;
140 
141  assert(ptr);
142  assert(src);
143 
144  if ((dst = ListItem(ptr, free_obj))==NULL) {
145  return NULL;
146  }
147 
148  if ((tmp = GetNextItem(src))) {
149  tmp->prev = dst;
150  }
151  dst->next = tmp;
152  dst->prev = src;
153  src->next = dst;
154 
155  return dst;
156 }
157 
158 LISTITEM* LinkPrev(LISTITEM* src, void* ptr, void (*free_obj) (void* obj))
159 {
160  Serror("Not implemented\n");
161  return NULL;
162 }
163 
164 LISTITEM* ListItem(void* ptr, void (*free_obj) (void* obj))
165 {
166  LISTITEM* item = NULL;
167 
168  assert(ptr);
169 
170  if ((item = (LISTITEM*) malloc(sizeof(LISTITEM)))==NULL) {
171  Serror("Failed to allocate new listitem\n");
172  return NULL;
173  }
174 
175  item->prev = NULL;
176  item->next = NULL;
177  item->obj = ptr;
178  item->free_obj = free_obj;
179  return item;
180 }
181 
182 int FreeListItem(LIST* list, LISTITEM* ptr)
183 {
184  if (ptr==NULL) {
185  Serror("Null value for LISTITEM\n");
186  return -1;
187  }
188 
189  if (ptr->obj) {
190  if (ptr->free_obj) {
191  ptr->free_obj(ptr->obj);
192  } else {
193  free(ptr->obj);
194  }
195  }
196 
197  return RemoveListItem(list, ptr);
198 }
199 
200 
201 int RemoveListItem(LIST* list, LISTITEM* ptr) {
202  LISTITEM* prev;
203  LISTITEM* next;
204 
205  assert(ptr);
206 
207  prev = GetPrevItem(ptr);
208  next = GetNextItem(ptr);
209 
210  if (prev) {
211  if (prev->next != ptr) {
212  Swarning("prev->next Sanity check failed on list\n");
213  }
214  prev->next = next;
215  if (next==NULL) {
216  assert (list->tail == ptr);
217  list->tail = prev;
218  if (list->curr == ptr) {
219  list->curr = prev;
220  }
221  }
222  }
223 
224  if (next) {
225  if (next->prev != ptr) {
226  Swarning("next->prev Sanity check failed on list\n");
227  }
228  next->prev = prev;
229  if (prev==NULL) {
230  assert (list->head == ptr);
231  list->head = next;
232  if (list->curr == ptr) {
233  list->curr = next;
234  }
235  }
236  }
237 
238  if ((next==NULL)&&(prev==NULL)) {
239  assert (list->tail==list->head);
240  list->tail = NULL;
241  list->head = NULL;
242  list->curr = NULL;
243  }
244 
245  free(ptr);
246  return 0;
247 
248 }
249 
250 
251 
252 int PopItem(LIST* list) {
253 
254  LISTITEM* head = list->head;
255 
256  if (list->head==NULL) {
257  Swarning("List already empty\n");
258  return -1;
259  }
260 
261  if (FreeListItem(list, head))
262  return -1;
263 
264  list->n--;
265 
266  if (list->head==NULL) {
267  if (list->n) {
268  Swarning("List seems empty (%d items remaining?)",list->n);
269  }
270  } else {
271  assert(list->curr);
272  assert(list->tail);
273  if (list->head==NULL) {
274  Serror ("List already empty\n");
275  }
276  /* set tail to head if only one item is remaining */
277  if (list->head->next==NULL) {
278  assert(list->n==1);
279  list->tail = list->head;
280  }
281  if (list->n<=0) {
282  Serror("Counter at %d, yet least not empty?\n",list->n);
283  return -1;
284  }
285  }
286 
287  return 0;
288 
289 }
290 
291 int ClearList(LIST* list)
292 {
293  int i;
294  while (list->head) {
295  PopItem(list);
296  }
297  i = list->n;
298 
299  if (i==0) {
300  if (list->head) {
301  Serror("List still has a head after clearing\n");
302  }
303  if (list->curr) {
304  Serror("List still points somewhere after clearing\n");
305  }
306  if (list->tail) {
307  Serror("List still has a tail after clearing\n");
308  }
309  } else {
310  Serror("List size not zero after clearing\n");
311  }
312 
313  free (list);
314 
315  return i;
316 }
317 
318 LISTITEM* FindItem (LIST* list, void* ptr)
319 {
320  return list->retrieve (list, ptr);
321 }
322 
323 
324 LISTITEM* ListLinearSearchRetrieve (struct List* list, void* ptr)
325 {
326  LISTITEM* item;
327 
328  item = FirstListItem (list);
329  while (item) {
330  if (item->obj == ptr) {
331  return item;
332  }
333  item = NextListItem (list);
334  }
335 
336  return NULL;
337 }
338 
339 
340 /* Get the size of the list */
341 int ListSize(LIST* list) {
342  return list->n;
343 }
344 
345 LISTITEM* GetItem (LIST* list, int n)
346 {
347  LISTITEM* item;
348 
349  if (n>=ListSize (list)) {
350  return NULL;
351  }
352  item = FirstListItem (list);
353  for (int i=0; i<n; i++) {
354  item = NextListItem (list);
355  }
356 
357  return item;
358 }
struct ListItem * next
next item
Definition: List.h:24
A list item.
Definition: List.h:20
int RemoveListItem(LIST *list, LISTITEM *ptr)
Definition: List.cpp:201
void * obj
data
Definition: List.h:21
LISTITEM * tail
tail item
Definition: List.h:40
LISTITEM * ListLinearSearchRetrieve(struct List *list, void *ptr)
Definition: List.cpp:324
LISTITEM * FindItem(LIST *list, void *ptr)
Finds the LISTITEM pointer corresponding to the data.
Definition: List.cpp:318
LISTITEM *(* retrieve)(struct List *list, void *ptr)
Method by which to search objects.
Definition: List.h:43
int ClearList(LIST *list)
Clear the list.
Definition: List.cpp:291
#define Swarning
Definition: learn_debug.h:11
int n
number of items
Definition: List.h:41
LISTITEM * ListAppend(LIST *list, void *p)
Append an item to the list.
Definition: List.cpp:34
LISTITEM * GetNextItem(LISTITEM *ptr)
Definition: List.cpp:115
LISTITEM * ListItem(void *ptr, void(*free_obj)(void *obj))
Definition: List.cpp:164
int FreeListItem(LIST *list, LISTITEM *ptr)
Definition: List.cpp:182
static Point p[4]
Definition: Convex.cpp:54
LISTITEM * LinkNext(LISTITEM *src, void *ptr, void(*free_obj)(void *obj))
Definition: List.cpp:136
LISTITEM * LastListItem(LIST *list)
Move to the last list item.
Definition: List.cpp:98
void(* free_obj)(void *obj)
free hook
Definition: List.h:22
LISTITEM * head
head item
Definition: List.h:39
LISTITEM * LinkPrev(LISTITEM *src, void *ptr, void(*free_obj)(void *obj))
Definition: List.cpp:158
LIST * List(void)
Create a new list.
Definition: List.cpp:16
LISTITEM * curr
current item
Definition: List.h:38
LISTITEM * FirstListItem(LIST *list)
Move to the first list item.
Definition: List.cpp:81
struct ListItem * prev
previous item
Definition: List.h:23
int PopItem(LIST *list)
Remove the topmost item of the list (also frees obj memory)
Definition: List.cpp:252
LISTITEM * NextListItem(LIST *list)
Advance one item.
Definition: List.cpp:67
A very simple list structure.
Definition: List.h:37
#define Serror
Definition: learn_debug.h:10
LISTITEM * GetPrevItem(LISTITEM *ptr)
Definition: List.cpp:126
int ListSize(LIST *list)
Get the size of the list.
Definition: List.cpp:341
LISTITEM * GetItem(LIST *list, int n)
Get the nth item of the list.
Definition: List.cpp:345