SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  * Written (W) 2012 Heiko Strathmann
10  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
11  */
12 
13 #ifndef _LIST_H_
14 #define _LIST_H_
15 
16 #include <shogun/lib/common.h>
17 #include <shogun/base/SGObject.h>
18 #include <shogun/base/Parameter.h>
19 
20 namespace shogun
21 {
23 class CListElement :public CSGObject
24 {
25  public:
28  : next(NULL), prev(NULL), data(NULL)
29  {
30  init();
31  }
32 
40  CListElement* p_prev = NULL,
41  CListElement* p_next = NULL)
42  {
43  init();
44 
45  this->data = p_data;
46  this->next = p_next;
47  this->prev = p_prev;
48  }
49 
51  virtual ~CListElement() { data = NULL; }
52 
54  inline virtual const char* get_name() const { return "ListElement"; }
55 
56  private:
57  void init()
58  {
59  m_parameters->add(&data, "data", "Data of this element.");
60  m_parameters->add((CSGObject**) &next, "next",
61  "Next element in list.");
63  "Next element in list.");
64  m_model_selection_parameters->add(&data, "data", "Data of this element.");
65  }
66 
67  public:
74 
75 };
76 
82 class CList : public CSGObject
83 {
84  public:
89  CList(bool p_delete_data=false) : CSGObject()
90  {
91  m_parameters->add(&delete_data, "delete_data",
92  "Delete data on destruction?");
93  m_parameters->add(&num_elements, "num_elements",
94  "Number of elements.");
95  m_parameters->add((CSGObject**) &first, "first",
96  "First element in list.");
97  m_model_selection_parameters->add((CSGObject**) &first, "first",
98  "First element in list.");
99 
100  first = NULL;
101  current = NULL;
102  last = NULL;
103 
104  num_elements = 0;
105  this->delete_data=p_delete_data;
106  }
107 
108  virtual ~CList()
109  {
110  SG_DEBUG("Destroying List %p\n", this);
111 
113  }
114 
116  inline void delete_all_elements()
117  {
118  while (get_num_elements())
119  {
121 
122  if (delete_data)
123  {
124  SG_DEBUG("SG_UNREF List Element %p\n", d);
125  SG_UNREF(d);
126  }
127  }
128 
129  first=NULL;
130  current=NULL;
131  last=NULL;
132  }
133 
138  inline int32_t get_num_elements() { return num_elements; }
139 
145  {
146  if (first != NULL)
147  {
148  current = first;
149  if (delete_data)
150  SG_REF(current->data);
151  return current->data;
152  }
153  else
154  return NULL;
155  }
156 
162  {
163  if (last != NULL)
164  {
165  current = last;
166  if (delete_data)
167  SG_REF(current->data);
168  return current->data;
169  }
170  else
171  return NULL;
172  }
173 
179  {
180  if ((current != NULL) && (current->next != NULL))
181  {
182  current = current->next;
183  if (delete_data)
184  SG_REF(current->data);
185  return current->data;
186  }
187  else
188  return NULL;
189  }
190 
196  {
197  if ((current != NULL) && (current->prev != NULL))
198  {
199  current = current->prev;
200  if (delete_data)
201  SG_REF(current->data);
202  return current->data;
203  }
204  else
205  return NULL;
206  }
207 
213  {
214  if (current != NULL)
215  {
216  if (delete_data)
217  SG_REF(current->data);
218  return current->data;
219  }
220  else
221  return NULL;
222  }
223 
224 
227 
234  {
235  if (first != NULL)
236  {
237  p_current = first;
238  if (delete_data)
239  SG_REF(p_current->data);
240  return p_current->data;
241  }
242  else
243  return NULL;
244  }
245 
252  {
253  if (last != NULL)
254  {
255  p_current = last;
256  if (delete_data)
257  SG_REF(p_current->data);
258  return p_current->data;
259  }
260  else
261  return NULL;
262  }
263 
270  {
271  if ((p_current != NULL) && (p_current->next != NULL))
272  {
273  p_current = p_current->next;
274  if (delete_data)
275  SG_REF(p_current->data);
276  return p_current->data;
277  }
278  else
279  return NULL;
280  }
281 
288  {
289  if ((p_current != NULL) && (p_current->prev != NULL))
290  {
291  p_current = p_current->prev;
292  if (delete_data)
293  SG_REF(p_current->data);
294  return p_current->data;
295  }
296  else
297  return NULL;
298  }
299 
306  {
307  if (p_current != NULL)
308  {
309  if (delete_data)
310  SG_REF(p_current->data);
311  return p_current->data;
312  }
313  else
314  return NULL;
315  }
317 
323  inline bool append_element(CSGObject* data)
324  {
325  if (current != NULL) // none available, case is shattered in insert_element()
326  {
328  if (e)
329  {
330  if (delete_data)
331  SG_UNREF(e);
332  // if successor exists use insert_element()
333  return insert_element(data);
334  }
335  else
336  {
337  // case with no successor but nonempty
338  CListElement* element;
339 
340  if ((element = new CListElement(data, current)) != NULL)
341  {
342  current->next = element;
343  current = element;
344  last = element;
345 
346  num_elements++;
347 
348  if (delete_data)
349  SG_REF(data);
350 
351  return true;
352  }
353  else
354  return false;
355  }
356  }
357  else
358  return insert_element(data);
359  }
360 
367  {
369  if (delete_data)
370  SG_UNREF(p);
371 
372  return append_element(data);
373  }
374 
380  inline bool push(CSGObject* data)
381  {
382  return append_element_at_listend(data);
383  }
384 
389  inline bool pop()
390  {
391  if (last)
392  {
393  if (first==last)
394  first=NULL;
395 
396  if (current==last)
397  {
398  if (first==last)
399  current=NULL;
400  else
401  current=current->prev;
402  }
403 
404  if (delete_data)
405  SG_UNREF(last->data);
406 
407  CListElement* temp=last;
408  last=last->prev;
409  SG_UNREF(temp);
410  if (last)
411  last->next=NULL;
412 
413  num_elements--;
414 
415  return true;
416  }
417  else
418  return false;
419  }
420 
426  inline bool insert_element(CSGObject* data)
427  {
428  CListElement* element;
429 
430  if (delete_data)
431  SG_REF(data);
432 
433  if (current == NULL)
434  {
435  if ((element = new CListElement(data)) != NULL)
436  {
437  current = element;
438  first = element;
439  last = element;
440 
441  num_elements++;
442 
443  return true;
444  }
445  else
446  return false;
447  }
448  else
449  {
450  if ((element = new CListElement(data, current->prev, current)) != NULL)
451  {
452  if (current->prev != NULL)
453  current->prev->next = element;
454  else
455  first = element;
456 
457  current->prev = element;
458  current = element;
459 
460  num_elements++;
461 
462  return true;
463  }
464  else
465  return false;
466  }
467  }
468 
476  {
477  CSGObject* data = get_current_element();
478 
479  if (num_elements>0)
480  num_elements--;
481 
482  if (data)
483  {
484  if (delete_data)
485  SG_UNREF(data);
486 
487  CListElement *element = current;
488 
489  if (element->prev)
490  element->prev->next = element->next;
491 
492  if (element->next)
493  element->next->prev = element->prev;
494 
495  if (element->next)
496  current = element->next;
497  else
498  current = element->prev;
499 
500  if (element == first)
501  first = element->next;
502 
503  if (element == last)
504  last = element->prev;
505 
506  delete element;
507 
508  return data;
509  }
510 
511  return NULL;
512  }
513 
515  {
517 
518  current = first;
519  CListElement* prev = NULL;
520  for (CListElement* cur=first; cur!=NULL; cur=cur->next)
521  {
522  cur->prev = prev;
523  prev = cur;
524  }
525  last = prev;
526  }
527 
529  void print_list()
530  {
531  CListElement* c=first;
532 
533  while (c)
534  {
535  SG_PRINT("\"%s\" at %p\n", c->data ? c->data->get_name() : "", c->data);
536  c=c->next;
537  }
538  }
539 
541  inline virtual const char* get_name() const { return "List"; }
542 
543  private:
545  bool delete_data;
547  CListElement* first;
549  CListElement* current;
551  CListElement* last;
553  int32_t num_elements;
554 };
555 }
556 #endif

SHOGUN Machine Learning Toolbox - Documentation