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 
00047 template <class T> class CList
00048 {
00049     public:
00054         CList(bool p_delete_data=false)
00055         {
00056             first  = NULL;
00057             current = NULL;
00058             last   = NULL;
00059 
00060             num_elements = 0;
00061             this->delete_data=p_delete_data;
00062         }
00063 
00064         ~CList()
00065         {
00066             while (get_num_elements())
00067             {
00068                 T d=delete_element();
00069 #ifdef HAVE_SWIG
00070                 if (delete_data)
00071                     SG_UNREF(d);
00072 #else
00073                 if (delete_data)
00074                     delete d;
00075 #endif
00076             }
00077         }
00078 
00083         inline int get_num_elements() { return num_elements; }
00084 
00089         inline T get_first_element()
00090         {
00091             if (first != NULL)
00092             {
00093                 current = first;
00094                 return current->data;
00095             }
00096             else 
00097                 return NULL;
00098         }
00099 
00104         inline T get_last_element()
00105         {
00106             if (last != NULL)
00107             {
00108                 current = last;
00109                 return current->data;
00110             }
00111             else 
00112                 return NULL;
00113         }
00114 
00119         inline T get_next_element()
00120         {
00121             if ((current != NULL) && (current->next != NULL))
00122             {
00123                 current = current->next;
00124                 return current->data;
00125             }
00126             else
00127                 return NULL;
00128         }
00129 
00134         inline T get_previous_element()
00135         {
00136             if ((current != NULL) && (current->prev != NULL))
00137             {
00138                 current = current->prev;
00139                 return current->data;
00140             }
00141             else
00142                 return NULL;
00143         }
00144 
00149         inline T get_current_element()
00150         {
00151             if (current != NULL)
00152                 return current->data;
00153             else 
00154                 return NULL;
00155         }
00156 
00157 
00160 
00166         inline T get_first_element(CListElement<T> *&p_current)
00167         {
00168             if (first != NULL)
00169             {
00170                 p_current = first;
00171                 return p_current->data;
00172             }
00173             else
00174                 return NULL;
00175         }
00176 
00182         inline T get_last_element(CListElement<T> *&p_current)
00183         {
00184             if (last != NULL)
00185             {
00186                 p_current = last;
00187                 return p_current->data;
00188             }
00189             else
00190                 return NULL;
00191         }
00192 
00198         inline T get_next_element(CListElement<T> *& p_current)
00199         {
00200             if ((p_current != NULL) && (p_current->next != NULL))
00201             {
00202                 p_current = p_current->next;
00203                 return p_current->data;
00204             }
00205             else
00206                 return NULL;
00207         }
00208 
00214         inline T get_previous_element(CListElement<T> *& p_current)
00215         {
00216             if ((p_current != NULL) && (p_current->prev != NULL))
00217             {
00218                 p_current = p_current->prev;
00219                 return p_current->data;
00220             }
00221             else
00222                 return NULL;
00223         }
00224 
00230         inline T get_current_element(CListElement<T> *& p_current)
00231         {
00232             if (p_current != NULL)
00233                 return p_current->data;
00234             else 
00235                 return NULL;
00236         }
00238 
00244         inline bool append_element(T data)
00245         {
00246             if (current != NULL)    // none available, case is shattered in insert_element()
00247             {
00248                 if (get_next_element())
00249                 {
00250                     // if successor exists use insert_element()
00251                     return insert_element(data);
00252                 }
00253                 else
00254                 {
00255                     // case with no successor but nonempty
00256                     CListElement<T>* element;
00257 
00258                     if ((element = new CListElement<T>(data, current)) != NULL)
00259                     {
00260                         current->next = element;
00261                         current       = element;
00262                         last         = element;
00263 
00264                         num_elements++;
00265 
00266                         return true;
00267                     }
00268                     else
00269                         return false;
00270                 }
00271             }
00272             else
00273                 return insert_element(data);
00274         }
00275 
00281         inline bool insert_element(T data)
00282         {
00283             CListElement<T>* element;
00284 
00285             if (current == NULL)
00286             {
00287                 if ((element = new CListElement<T> (data)) != NULL)
00288                 {
00289                     current = element;
00290                     first  = element;
00291                     last   = element;
00292 
00293                     num_elements++;
00294 
00295                     return true;
00296                 }
00297                 else
00298                     return false;
00299             }
00300             else
00301             {
00302                 if ((element = new CListElement<T>(data, current->prev, current)) != NULL)
00303                 {
00304                     if (current->prev != NULL)
00305                         current->prev->next = element;
00306                     else
00307                         first = element;
00308 
00309                     current->prev = element;
00310                     current       = element;
00311 
00312                     num_elements++;
00313 
00314                     return true;
00315                 }
00316                 else
00317                     return false;
00318             }
00319         }
00320 
00327         inline T delete_element(void)
00328         {
00329             T data = get_current_element();
00330 
00331             if (data)
00332             {
00333                 CListElement<T> *element = current;
00334 
00335                 if (element->prev)
00336                     element->prev->next = element->next;
00337 
00338                 if (element->next)
00339                     element->next->prev = element->prev;
00340 
00341                 if (element->next)
00342                     current = element->next;
00343                 else
00344                     current = element->prev;
00345 
00346                 if (element == first)
00347                     first = element->next;
00348 
00349                 if (element == last)
00350                     last  = element->prev;
00351 
00352                 delete element;
00353 
00354                 num_elements--;
00355 
00356                 return data;
00357             } 
00358 
00359             return NULL;
00360         }
00361 
00362     private:
00364         bool delete_data;
00366         CListElement<T>* first;
00368         CListElement<T>* current;
00370         CListElement<T>* last;
00372         int num_elements;
00373 };
00374 #endif

SHOGUN Machine Learning Toolbox - Documentation