Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _LIST_H_
00013 #define _LIST_H_
00014
00015 #include <shogun/lib/common.h>
00016 #include <shogun/base/SGObject.h>
00017 #include <shogun/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)
00310 {
00311 CSGObject* e=get_next_element();
00312 if (e)
00313 {
00314 if (delete_data)
00315 SG_UNREF(e);
00316
00317 return insert_element(data);
00318 }
00319 else
00320 {
00321
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