Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _LIST_H_
00014 #define _LIST_H_
00015
00016 #include <shogun/lib/common.h>
00017 #include <shogun/base/SGObject.h>
00018 #include <shogun/base/Parameter.h>
00019
00020 namespace shogun
00021 {
00023 class CListElement :public CSGObject
00024 {
00025 public:
00027 CListElement()
00028 : next(NULL), prev(NULL), data(NULL)
00029 {
00030 init();
00031 }
00032
00039 CListElement(CSGObject* p_data,
00040 CListElement* p_prev = NULL,
00041 CListElement* p_next = NULL)
00042 {
00043 init();
00044
00045 this->data = p_data;
00046 this->next = p_next;
00047 this->prev = p_prev;
00048 }
00049
00051 virtual ~CListElement() { data = NULL; }
00052
00054 virtual const char* get_name() const { return "ListElement"; }
00055
00056 private:
00057 void init()
00058 {
00059 m_parameters->add(&data, "data", "Data of this element.");
00060 m_parameters->add((CSGObject**) &next, "next",
00061 "Next element in list.");
00062 m_model_selection_parameters->add((CSGObject**) &next, "next",
00063 "Next element in list.");
00064 m_model_selection_parameters->add(&data, "data", "Data of this element.");
00065 }
00066
00067 public:
00069 CListElement* next;
00071 CListElement* prev;
00073 CSGObject* data;
00074
00075 };
00076
00082 class CList : public CSGObject
00083 {
00084 public:
00089 CList(bool p_delete_data=false) : CSGObject()
00090 {
00091 m_parameters->add(&delete_data, "delete_data",
00092 "Delete data on destruction?");
00093 m_parameters->add(&num_elements, "num_elements",
00094 "Number of elements.");
00095 m_parameters->add((CSGObject**) &first, "first",
00096 "First element in list.");
00097 m_model_selection_parameters->add((CSGObject**) &first, "first",
00098 "First element in list.");
00099
00100 first = NULL;
00101 current = NULL;
00102 last = NULL;
00103
00104 num_elements = 0;
00105 this->delete_data=p_delete_data;
00106 }
00107
00108 virtual ~CList()
00109 {
00110 SG_DEBUG("Destroying List %p\n", this);
00111
00112 delete_all_elements();
00113 }
00114
00116 inline void delete_all_elements()
00117 {
00118 while (get_num_elements())
00119 {
00120 CSGObject* d=delete_element();
00121
00122 if (delete_data)
00123 {
00124 SG_DEBUG("SG_UNREF List Element %p\n", d);
00125 SG_UNREF(d);
00126 }
00127 }
00128
00129 first=NULL;
00130 current=NULL;
00131 last=NULL;
00132 }
00133
00138 inline int32_t get_num_elements() { return num_elements; }
00139
00144 inline CSGObject* get_first_element()
00145 {
00146 if (first != NULL)
00147 {
00148 current = first;
00149 if (delete_data)
00150 SG_REF(current->data);
00151 return current->data;
00152 }
00153 else
00154 return NULL;
00155 }
00156
00161 inline CSGObject* get_last_element()
00162 {
00163 if (last != NULL)
00164 {
00165 current = last;
00166 if (delete_data)
00167 SG_REF(current->data);
00168 return current->data;
00169 }
00170 else
00171 return NULL;
00172 }
00173
00178 inline CSGObject* get_next_element()
00179 {
00180 if ((current != NULL) && (current->next != NULL))
00181 {
00182 current = current->next;
00183 if (delete_data)
00184 SG_REF(current->data);
00185 return current->data;
00186 }
00187 else
00188 return NULL;
00189 }
00190
00195 inline CSGObject* get_previous_element()
00196 {
00197 if ((current != NULL) && (current->prev != NULL))
00198 {
00199 current = current->prev;
00200 if (delete_data)
00201 SG_REF(current->data);
00202 return current->data;
00203 }
00204 else
00205 return NULL;
00206 }
00207
00212 inline CSGObject* get_current_element()
00213 {
00214 if (current != NULL)
00215 {
00216 if (delete_data)
00217 SG_REF(current->data);
00218 return current->data;
00219 }
00220 else
00221 return NULL;
00222 }
00223
00224
00227
00233 inline CSGObject* get_first_element(CListElement*& p_current)
00234 {
00235 if (first != NULL)
00236 {
00237 p_current = first;
00238 if (delete_data)
00239 SG_REF(p_current->data);
00240 return p_current->data;
00241 }
00242 else
00243 return NULL;
00244 }
00245
00251 inline CSGObject* get_last_element(CListElement*& p_current)
00252 {
00253 if (last != NULL)
00254 {
00255 p_current = last;
00256 if (delete_data)
00257 SG_REF(p_current->data);
00258 return p_current->data;
00259 }
00260 else
00261 return NULL;
00262 }
00263
00269 inline CSGObject* get_next_element(CListElement*& p_current)
00270 {
00271 if ((p_current != NULL) && (p_current->next != NULL))
00272 {
00273 p_current = p_current->next;
00274 if (delete_data)
00275 SG_REF(p_current->data);
00276 return p_current->data;
00277 }
00278 else
00279 return NULL;
00280 }
00281
00287 inline CSGObject* get_previous_element(CListElement*& p_current)
00288 {
00289 if ((p_current != NULL) && (p_current->prev != NULL))
00290 {
00291 p_current = p_current->prev;
00292 if (delete_data)
00293 SG_REF(p_current->data);
00294 return p_current->data;
00295 }
00296 else
00297 return NULL;
00298 }
00299
00305 inline CSGObject* get_current_element(CListElement*& p_current)
00306 {
00307 if (p_current != NULL)
00308 {
00309 if (delete_data)
00310 SG_REF(p_current->data);
00311 return p_current->data;
00312 }
00313 else
00314 return NULL;
00315 }
00317
00323 inline bool append_element(CSGObject* data)
00324 {
00325 if (current != NULL)
00326 {
00327 CSGObject* e=get_next_element();
00328 if (e)
00329 {
00330 if (delete_data)
00331 SG_UNREF(e);
00332
00333 return insert_element(data);
00334 }
00335 else
00336 {
00337
00338 CListElement* element;
00339
00340 if ((element = new CListElement(data, current)) != NULL)
00341 {
00342 current->next = element;
00343 current = element;
00344 last = element;
00345
00346 num_elements++;
00347
00348 if (delete_data)
00349 SG_REF(data);
00350
00351 return true;
00352 }
00353 else
00354 return false;
00355 }
00356 }
00357 else
00358 return insert_element(data);
00359 }
00360
00366 inline bool append_element_at_listend(CSGObject* data)
00367 {
00368 CSGObject* p = get_last_element();
00369 if (delete_data)
00370 SG_UNREF(p);
00371
00372 return append_element(data);
00373 }
00374
00380 inline bool push(CSGObject* data)
00381 {
00382 return append_element_at_listend(data);
00383 }
00384
00389 inline bool pop()
00390 {
00391 if (last)
00392 {
00393 if (first==last)
00394 first=NULL;
00395
00396 if (current==last)
00397 {
00398 if (first==last)
00399 current=NULL;
00400 else
00401 current=current->prev;
00402 }
00403
00404 if (delete_data)
00405 SG_UNREF(last->data);
00406
00407 CListElement* temp=last;
00408 last=last->prev;
00409 SG_UNREF(temp);
00410 if (last)
00411 last->next=NULL;
00412
00413 num_elements--;
00414
00415 return true;
00416 }
00417 else
00418 return false;
00419 }
00420
00426 inline bool insert_element(CSGObject* data)
00427 {
00428 CListElement* element;
00429
00430 if (delete_data)
00431 SG_REF(data);
00432
00433 if (current == NULL)
00434 {
00435 if ((element = new CListElement(data)) != NULL)
00436 {
00437 current = element;
00438 first = element;
00439 last = element;
00440
00441 num_elements++;
00442
00443 return true;
00444 }
00445 else
00446 return false;
00447 }
00448 else
00449 {
00450 if ((element = new CListElement(data, current->prev, current)) != NULL)
00451 {
00452 if (current->prev != NULL)
00453 current->prev->next = element;
00454 else
00455 first = element;
00456
00457 current->prev = element;
00458 current = element;
00459
00460 num_elements++;
00461
00462 return true;
00463 }
00464 else
00465 return false;
00466 }
00467 }
00468
00475 inline CSGObject* delete_element()
00476 {
00477 CSGObject* data = get_current_element();
00478
00479 if (num_elements>0)
00480 num_elements--;
00481
00482 if (data)
00483 {
00484 if (delete_data)
00485 SG_UNREF(data);
00486
00487 CListElement *element = current;
00488
00489 if (element->prev)
00490 element->prev->next = element->next;
00491
00492 if (element->next)
00493 element->next->prev = element->prev;
00494
00495 if (element->next)
00496 current = element->next;
00497 else
00498 current = element->prev;
00499
00500 if (element == first)
00501 first = element->next;
00502
00503 if (element == last)
00504 last = element->prev;
00505
00506 delete element;
00507
00508 return data;
00509 }
00510
00511 return NULL;
00512 }
00513
00514 virtual void load_serializable_post() throw (ShogunException)
00515 {
00516 CSGObject::load_serializable_post();
00517
00518 current = first;
00519 CListElement* prev = NULL;
00520 for (CListElement* cur=first; cur!=NULL; cur=cur->next)
00521 {
00522 cur->prev = prev;
00523 prev = cur;
00524 }
00525 last = prev;
00526 }
00527
00529 void print_list()
00530 {
00531 CListElement* c=first;
00532
00533 while (c)
00534 {
00535 SG_PRINT("\"%s\" at %p\n", c->data ? c->data->get_name() : "", c->data);
00536 c=c->next;
00537 }
00538 }
00539
00541 virtual const char* get_name() const { return "List"; }
00542
00543 private:
00545 bool delete_data;
00547 CListElement* first;
00549 CListElement* current;
00551 CListElement* last;
00553 int32_t num_elements;
00554 };
00555 }
00556 #endif