SHOGUN v0.9.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 1999-2009 Soeren Sonnenburg 00008 * Written (W) 1999-2008 Gunnar Raetsch 00009 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00010 */ 00011 00012 #ifndef _LIST_H_ 00013 #define _LIST_H_ 00014 00015 #include "lib/common.h" 00016 #include "base/SGObject.h" 00017 #include "base/Parameter.h" 00018 00019 namespace shogun 00020 { 00022 class CListElement :public CSGObject 00023 { 00024 public: 00026 CListElement() 00027 : next(NULL), prev(NULL), data(NULL) 00028 { 00029 init(); 00030 } 00031 00038 CListElement(CSGObject* p_data, 00039 CListElement* p_prev = NULL, 00040 CListElement* p_next = NULL) 00041 { 00042 init(); 00043 00044 this->data = p_data; 00045 this->next = p_next; 00046 this->prev = p_prev; 00047 } 00048 00050 virtual ~CListElement() { data = NULL; } 00051 00053 inline virtual const char* get_name(void) const { return "ListElement"; } 00054 00055 private: 00056 void init() 00057 { 00058 m_parameters->add(&data, "data", "Data of this element."); 00059 m_parameters->add((CSGObject**) &next, "next", 00060 "Next element in list."); 00061 } 00062 00063 public: 00065 CListElement* next; 00067 CListElement* prev; 00069 CSGObject* data; 00070 00071 }; 00072 00078 class CList : public CSGObject 00079 { 00080 public: 00085 CList(bool p_delete_data=false) : CSGObject() 00086 { 00087 m_parameters->add(&delete_data, "delete_data", 00088 "Delete data on destruction?"); 00089 m_parameters->add(&num_elements, "num_elements", 00090 "Number of elements."); 00091 m_parameters->add((CSGObject**) &first, "first", 00092 "First element in list."); 00093 00094 first = NULL; 00095 current = NULL; 00096 last = NULL; 00097 00098 num_elements = 0; 00099 this->delete_data=p_delete_data; 00100 } 00101 00102 virtual ~CList() 00103 { 00104 SG_DEBUG("Destroying List %p\n", this); 00105 00106 while (get_num_elements()) 00107 { 00108 CSGObject* d=delete_element(); 00109 00110 if (delete_data) 00111 { 00112 SG_DEBUG("Destroying List Element %p\n", d); 00113 SG_UNREF(d); 00114 } 00115 } 00116 } 00117 00122 inline int32_t get_num_elements() { return num_elements; } 00123 00128 inline CSGObject* get_first_element() 00129 { 00130 if (first != NULL) 00131 { 00132 current = first; 00133 if (delete_data) 00134 SG_REF(current->data); 00135 return current->data; 00136 } 00137 else 00138 return NULL; 00139 } 00140 00145 inline CSGObject* get_last_element() 00146 { 00147 if (last != NULL) 00148 { 00149 current = last; 00150 if (delete_data) 00151 SG_REF(current->data); 00152 return current->data; 00153 } 00154 else 00155 return NULL; 00156 } 00157 00162 inline CSGObject* get_next_element() 00163 { 00164 if ((current != NULL) && (current->next != NULL)) 00165 { 00166 current = current->next; 00167 if (delete_data) 00168 SG_REF(current->data); 00169 return current->data; 00170 } 00171 else 00172 return NULL; 00173 } 00174 00179 inline CSGObject* get_previous_element() 00180 { 00181 if ((current != NULL) && (current->prev != NULL)) 00182 { 00183 current = current->prev; 00184 if (delete_data) 00185 SG_REF(current->data); 00186 return current->data; 00187 } 00188 else 00189 return NULL; 00190 } 00191 00196 inline CSGObject* get_current_element() 00197 { 00198 if (current != NULL) 00199 { 00200 if (delete_data) 00201 SG_REF(current->data); 00202 return current->data; 00203 } 00204 else 00205 return NULL; 00206 } 00207 00208 00211 00217 inline CSGObject* get_first_element(CListElement*& p_current) 00218 { 00219 if (first != NULL) 00220 { 00221 p_current = first; 00222 if (delete_data) 00223 SG_REF(p_current->data); 00224 return p_current->data; 00225 } 00226 else 00227 return NULL; 00228 } 00229 00235 inline CSGObject* get_last_element(CListElement*& p_current) 00236 { 00237 if (last != NULL) 00238 { 00239 p_current = last; 00240 if (delete_data) 00241 SG_REF(p_current->data); 00242 return p_current->data; 00243 } 00244 else 00245 return NULL; 00246 } 00247 00253 inline CSGObject* get_next_element(CListElement*& p_current) 00254 { 00255 if ((p_current != NULL) && (p_current->next != NULL)) 00256 { 00257 p_current = p_current->next; 00258 if (delete_data) 00259 SG_REF(p_current->data); 00260 return p_current->data; 00261 } 00262 else 00263 return NULL; 00264 } 00265 00271 inline CSGObject* get_previous_element(CListElement*& p_current) 00272 { 00273 if ((p_current != NULL) && (p_current->prev != NULL)) 00274 { 00275 p_current = p_current->prev; 00276 if (delete_data) 00277 SG_REF(p_current->data); 00278 return p_current->data; 00279 } 00280 else 00281 return NULL; 00282 } 00283 00289 inline CSGObject* get_current_element(CListElement*& p_current) 00290 { 00291 if (p_current != NULL) 00292 { 00293 if (delete_data) 00294 SG_REF(p_current->data); 00295 return p_current->data; 00296 } 00297 else 00298 return NULL; 00299 } 00301 00307 inline bool append_element(CSGObject* data) 00308 { 00309 if (current != NULL) // none available, case is shattered in insert_element() 00310 { 00311 CSGObject* e=get_next_element(); 00312 if (e) 00313 { 00314 if (delete_data) 00315 SG_UNREF(e); 00316 // if successor exists use insert_element() 00317 return insert_element(data); 00318 } 00319 else 00320 { 00321 // case with no successor but nonempty 00322 CListElement* element; 00323 00324 if ((element = new CListElement(data, current)) != NULL) 00325 { 00326 current->next = element; 00327 current = element; 00328 last = element; 00329 00330 num_elements++; 00331 00332 if (delete_data) 00333 SG_REF(data); 00334 00335 return true; 00336 } 00337 else 00338 return false; 00339 } 00340 } 00341 else 00342 return insert_element(data); 00343 } 00344 00350 inline bool append_element_at_listend(CSGObject* data) 00351 { 00352 CSGObject* p = get_last_element(); 00353 if (delete_data) 00354 SG_UNREF(p); 00355 00356 return append_element(data); 00357 } 00358 00364 inline bool insert_element(CSGObject* data) 00365 { 00366 CListElement* element; 00367 00368 if (delete_data) 00369 SG_REF(data); 00370 00371 if (current == NULL) 00372 { 00373 if ((element = new CListElement(data)) != NULL) 00374 { 00375 current = element; 00376 first = element; 00377 last = element; 00378 00379 num_elements++; 00380 00381 return true; 00382 } 00383 else 00384 return false; 00385 } 00386 else 00387 { 00388 if ((element = new CListElement(data, current->prev, current)) != NULL) 00389 { 00390 if (current->prev != NULL) 00391 current->prev->next = element; 00392 else 00393 first = element; 00394 00395 current->prev = element; 00396 current = element; 00397 00398 num_elements++; 00399 00400 return true; 00401 } 00402 else 00403 return false; 00404 } 00405 } 00406 00413 inline CSGObject* delete_element(void) 00414 { 00415 CSGObject* data = get_current_element(); 00416 00417 if (num_elements>0) 00418 num_elements--; 00419 00420 if (data) 00421 { 00422 if (delete_data) 00423 SG_UNREF(data); 00424 00425 CListElement *element = current; 00426 00427 if (element->prev) 00428 element->prev->next = element->next; 00429 00430 if (element->next) 00431 element->next->prev = element->prev; 00432 00433 if (element->next) 00434 current = element->next; 00435 else 00436 current = element->prev; 00437 00438 if (element == first) 00439 first = element->next; 00440 00441 if (element == last) 00442 last = element->prev; 00443 00444 delete element; 00445 00446 return data; 00447 } 00448 00449 return NULL; 00450 } 00451 00452 virtual void load_serializable_post() throw (ShogunException) 00453 { 00454 CSGObject::load_serializable_post(); 00455 00456 current = first; 00457 CListElement* prev = NULL; 00458 for (CListElement* cur=first; cur!=NULL; cur=cur->next) 00459 { 00460 cur->prev = prev; 00461 prev = cur; 00462 } 00463 last = prev; 00464 } 00465 00467 inline virtual const char* get_name(void) const { return "List"; } 00468 00469 private: 00471 bool delete_data; 00473 CListElement* first; 00475 CListElement* current; 00477 CListElement* last; 00479 int32_t num_elements; 00480 }; 00481 } 00482 #endif