List.h

Go to the documentation of this file.
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 <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)    // 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation