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-2008 Soeren Sonnenburg
00008  * Written (W) 1999-2008 Gunnar Raetsch
00009  * Copyright (C) 1999-2008 Fraunhofer Institute FIRST and Max-Planck-Society
00010  */
00011 
00012 #ifndef _LIST_H_
00013 #define _LIST_H_
00014 
00015 #include "lib/common.h"
00016 
00018 template <class T> class CListElement
00019 {
00020     public:
00022         CListElement* next;
00024         CListElement* prev;
00026         T data;
00027 
00028     public:
00035         CListElement(T p_data, CListElement* p_prev = NULL, CListElement* p_next = NULL)
00036         {
00037             this->data = p_data;
00038             this->next = p_next;
00039             this->prev = p_prev;
00040         };
00041 
00043         ~CListElement() { data = NULL; }
00044 };
00045 
00050 template <class T> class CList
00051 {
00052     public:
00057         CList(bool p_delete_data=false)
00058         {
00059             first  = NULL;
00060             current = NULL;
00061             last   = NULL;
00062 
00063             num_elements = 0;
00064             this->delete_data=p_delete_data;
00065         }
00066 
00067         ~CList()
00068         {
00069             while (get_num_elements())
00070             {
00071                 T d=delete_element();
00072 #ifdef HAVE_SWIG
00073                 if (delete_data)
00074                     SG_UNREF(d);
00075 #else
00076                 if (delete_data)
00077                     delete d;
00078 #endif
00079             }
00080         }
00081 
00086         inline int32_t get_num_elements() { return num_elements; }
00087 
00092         inline T get_first_element()
00093         {
00094             if (first != NULL)
00095             {
00096                 current = first;
00097                 return current->data;
00098             }
00099             else 
00100                 return NULL;
00101         }
00102 
00107         inline T get_last_element()
00108         {
00109             if (last != NULL)
00110             {
00111                 current = last;
00112                 return current->data;
00113             }
00114             else 
00115                 return NULL;
00116         }
00117 
00122         inline T get_next_element()
00123         {
00124             if ((current != NULL) && (current->next != NULL))
00125             {
00126                 current = current->next;
00127                 return current->data;
00128             }
00129             else
00130                 return NULL;
00131         }
00132 
00137         inline T get_previous_element()
00138         {
00139             if ((current != NULL) && (current->prev != NULL))
00140             {
00141                 current = current->prev;
00142                 return current->data;
00143             }
00144             else
00145                 return NULL;
00146         }
00147 
00152         inline T get_current_element()
00153         {
00154             if (current != NULL)
00155                 return current->data;
00156             else 
00157                 return NULL;
00158         }
00159 
00160 
00163 
00169         inline T get_first_element(CListElement<T> *&p_current)
00170         {
00171             if (first != NULL)
00172             {
00173                 p_current = first;
00174                 return p_current->data;
00175             }
00176             else
00177                 return NULL;
00178         }
00179 
00185         inline T get_last_element(CListElement<T> *&p_current)
00186         {
00187             if (last != NULL)
00188             {
00189                 p_current = last;
00190                 return p_current->data;
00191             }
00192             else
00193                 return NULL;
00194         }
00195 
00201         inline T get_next_element(CListElement<T> *& p_current)
00202         {
00203             if ((p_current != NULL) && (p_current->next != NULL))
00204             {
00205                 p_current = p_current->next;
00206                 return p_current->data;
00207             }
00208             else
00209                 return NULL;
00210         }
00211 
00217         inline T get_previous_element(CListElement<T> *& p_current)
00218         {
00219             if ((p_current != NULL) && (p_current->prev != NULL))
00220             {
00221                 p_current = p_current->prev;
00222                 return p_current->data;
00223             }
00224             else
00225                 return NULL;
00226         }
00227 
00233         inline T get_current_element(CListElement<T> *& p_current)
00234         {
00235             if (p_current != NULL)
00236                 return p_current->data;
00237             else 
00238                 return NULL;
00239         }
00241 
00247         inline bool append_element(T data)
00248         {
00249             if (current != NULL)    // none available, case is shattered in insert_element()
00250             {
00251                 if (get_next_element())
00252                 {
00253                     // if successor exists use insert_element()
00254                     return insert_element(data);
00255                 }
00256                 else
00257                 {
00258                     // case with no successor but nonempty
00259                     CListElement<T>* element;
00260 
00261                     if ((element = new CListElement<T>(data, current)) != NULL)
00262                     {
00263                         current->next = element;
00264                         current       = element;
00265                         last         = element;
00266 
00267                         num_elements++;
00268 
00269                         return true;
00270                     }
00271                     else
00272                         return false;
00273                 }
00274             }
00275             else
00276                 return insert_element(data);
00277         }
00278 
00284         inline bool insert_element(T data)
00285         {
00286             CListElement<T>* element;
00287 
00288             if (current == NULL)
00289             {
00290                 if ((element = new CListElement<T> (data)) != NULL)
00291                 {
00292                     current = element;
00293                     first  = element;
00294                     last   = element;
00295 
00296                     num_elements++;
00297 
00298                     return true;
00299                 }
00300                 else
00301                     return false;
00302             }
00303             else
00304             {
00305                 if ((element = new CListElement<T>(data, current->prev, current)) != NULL)
00306                 {
00307                     if (current->prev != NULL)
00308                         current->prev->next = element;
00309                     else
00310                         first = element;
00311 
00312                     current->prev = element;
00313                     current       = element;
00314 
00315                     num_elements++;
00316 
00317                     return true;
00318                 }
00319                 else
00320                     return false;
00321             }
00322         }
00323 
00330         inline T delete_element(void)
00331         {
00332             T data = get_current_element();
00333 
00334             if (data)
00335             {
00336                 CListElement<T> *element = current;
00337 
00338                 if (element->prev)
00339                     element->prev->next = element->next;
00340 
00341                 if (element->next)
00342                     element->next->prev = element->prev;
00343 
00344                 if (element->next)
00345                     current = element->next;
00346                 else
00347                     current = element->prev;
00348 
00349                 if (element == first)
00350                     first = element->next;
00351 
00352                 if (element == last)
00353                     last  = element->prev;
00354 
00355                 delete element;
00356 
00357                 num_elements--;
00358 
00359                 return data;
00360             } 
00361 
00362             return NULL;
00363         }
00364 
00365     private:
00367         bool delete_data;
00369         CListElement<T>* first;
00371         CListElement<T>* current;
00373         CListElement<T>* last;
00375         int32_t num_elements;
00376 };
00377 #endif

SHOGUN Machine Learning Toolbox - Documentation