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  * Written (W) 2012 Heiko Strathmann
00010  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
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)    // none available, case is shattered in insert_element()
00326             {
00327                 CSGObject* e=get_next_element();
00328                 if (e)
00329                 {
00330                     if (delete_data)
00331                         SG_UNREF(e);
00332                     // if successor exists use insert_element()
00333                     return insert_element(data);
00334                 }
00335                 else
00336                 {
00337                     // case with no successor but nonempty
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation