SHOGUN  v1.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
List.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 1999-2009 Soeren Sonnenburg
8  * Written (W) 1999-2008 Gunnar Raetsch
9  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
10  */
11 
12 #ifndef _LIST_H_
13 #define _LIST_H_
14 
15 #include <shogun/lib/common.h>
16 #include <shogun/base/SGObject.h>
17 #include <shogun/base/Parameter.h>
18 
19 namespace shogun
20 {
22 class CListElement :public CSGObject
23 {
24  public:
27  : next(NULL), prev(NULL), data(NULL)
28  {
29  init();
30  }
31 
39  CListElement* p_prev = NULL,
40  CListElement* p_next = NULL)
41  {
42  init();
43 
44  this->data = p_data;
45  this->next = p_next;
46  this->prev = p_prev;
47  }
48 
50  virtual ~CListElement() { data = NULL; }
51 
53  inline virtual const char* get_name() const { return "ListElement"; }
54 
55  private:
56  void init()
57  {
58  m_parameters->add(&data, "data", "Data of this element.");
59  m_parameters->add((CSGObject**) &next, "next",
60  "Next element in list.");
61  }
62 
63  public:
70 
71 };
72 
78 class CList : public CSGObject
79 {
80  public:
85  CList(bool p_delete_data=false) : CSGObject()
86  {
87  m_parameters->add(&delete_data, "delete_data",
88  "Delete data on destruction?");
89  m_parameters->add(&num_elements, "num_elements",
90  "Number of elements.");
91  m_parameters->add((CSGObject**) &first, "first",
92  "First element in list.");
93 
94  first = NULL;
95  current = NULL;
96  last = NULL;
97 
98  num_elements = 0;
99  this->delete_data=p_delete_data;
100  }
101 
102  virtual ~CList()
103  {
104  SG_DEBUG("Destroying List %p\n", this);
105 
106  while (get_num_elements())
107  {
109 
110  if (delete_data)
111  {
112  SG_DEBUG("Destroying List Element %p\n", d);
113  SG_UNREF(d);
114  }
115  }
116  }
117 
122  inline int32_t get_num_elements() { return num_elements; }
123 
129  {
130  if (first != NULL)
131  {
132  current = first;
133  if (delete_data)
134  SG_REF(current->data);
135  return current->data;
136  }
137  else
138  return NULL;
139  }
140 
146  {
147  if (last != NULL)
148  {
149  current = last;
150  if (delete_data)
151  SG_REF(current->data);
152  return current->data;
153  }
154  else
155  return NULL;
156  }
157 
163  {
164  if ((current != NULL) && (current->next != NULL))
165  {
166  current = current->next;
167  if (delete_data)
168  SG_REF(current->data);
169  return current->data;
170  }
171  else
172  return NULL;
173  }
174 
180  {
181  if ((current != NULL) && (current->prev != NULL))
182  {
183  current = current->prev;
184  if (delete_data)
185  SG_REF(current->data);
186  return current->data;
187  }
188  else
189  return NULL;
190  }
191 
197  {
198  if (current != NULL)
199  {
200  if (delete_data)
201  SG_REF(current->data);
202  return current->data;
203  }
204  else
205  return NULL;
206  }
207 
208 
211 
218  {
219  if (first != NULL)
220  {
221  p_current = first;
222  if (delete_data)
223  SG_REF(p_current->data);
224  return p_current->data;
225  }
226  else
227  return NULL;
228  }
229 
236  {
237  if (last != NULL)
238  {
239  p_current = last;
240  if (delete_data)
241  SG_REF(p_current->data);
242  return p_current->data;
243  }
244  else
245  return NULL;
246  }
247 
254  {
255  if ((p_current != NULL) && (p_current->next != NULL))
256  {
257  p_current = p_current->next;
258  if (delete_data)
259  SG_REF(p_current->data);
260  return p_current->data;
261  }
262  else
263  return NULL;
264  }
265 
272  {
273  if ((p_current != NULL) && (p_current->prev != NULL))
274  {
275  p_current = p_current->prev;
276  if (delete_data)
277  SG_REF(p_current->data);
278  return p_current->data;
279  }
280  else
281  return NULL;
282  }
283 
290  {
291  if (p_current != NULL)
292  {
293  if (delete_data)
294  SG_REF(p_current->data);
295  return p_current->data;
296  }
297  else
298  return NULL;
299  }
301 
307  inline bool append_element(CSGObject* data)
308  {
309  if (current != NULL) // none available, case is shattered in insert_element()
310  {
312  if (e)
313  {
314  if (delete_data)
315  SG_UNREF(e);
316  // if successor exists use insert_element()
317  return insert_element(data);
318  }
319  else
320  {
321  // case with no successor but nonempty
322  CListElement* element;
323 
324  if ((element = new CListElement(data, current)) != NULL)
325  {
326  current->next = element;
327  current = element;
328  last = element;
329 
330  num_elements++;
331 
332  if (delete_data)
333  SG_REF(data);
334 
335  return true;
336  }
337  else
338  return false;
339  }
340  }
341  else
342  return insert_element(data);
343  }
344 
351  {
353  if (delete_data)
354  SG_UNREF(p);
355 
356  return append_element(data);
357  }
358 
364  inline bool insert_element(CSGObject* data)
365  {
366  CListElement* element;
367 
368  if (delete_data)
369  SG_REF(data);
370 
371  if (current == NULL)
372  {
373  if ((element = new CListElement(data)) != NULL)
374  {
375  current = element;
376  first = element;
377  last = element;
378 
379  num_elements++;
380 
381  return true;
382  }
383  else
384  return false;
385  }
386  else
387  {
388  if ((element = new CListElement(data, current->prev, current)) != NULL)
389  {
390  if (current->prev != NULL)
391  current->prev->next = element;
392  else
393  first = element;
394 
395  current->prev = element;
396  current = element;
397 
398  num_elements++;
399 
400  return true;
401  }
402  else
403  return false;
404  }
405  }
406 
414  {
415  CSGObject* data = get_current_element();
416 
417  if (num_elements>0)
418  num_elements--;
419 
420  if (data)
421  {
422  if (delete_data)
423  SG_UNREF(data);
424 
425  CListElement *element = current;
426 
427  if (element->prev)
428  element->prev->next = element->next;
429 
430  if (element->next)
431  element->next->prev = element->prev;
432 
433  if (element->next)
434  current = element->next;
435  else
436  current = element->prev;
437 
438  if (element == first)
439  first = element->next;
440 
441  if (element == last)
442  last = element->prev;
443 
444  delete element;
445 
446  return data;
447  }
448 
449  return NULL;
450  }
451 
453  {
455 
456  current = first;
457  CListElement* prev = NULL;
458  for (CListElement* cur=first; cur!=NULL; cur=cur->next)
459  {
460  cur->prev = prev;
461  prev = cur;
462  }
463  last = prev;
464  }
465 
467  inline virtual const char* get_name() const { return "List"; }
468 
469  private:
471  bool delete_data;
473  CListElement* first;
475  CListElement* current;
477  CListElement* last;
479  int32_t num_elements;
480 };
481 }
482 #endif

SHOGUN Machine Learning Toolbox - Documentation