tpl_dynSlist.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
00041 */
00042 
00043 
00044 # ifndef TPL_DYNSLIST_H
00045 # define TPL_DYNSLIST_H
00046 
00047 # include <tpl_slist.H>
00048 
00049 using namespace Aleph;
00050 
00051 namespace Aleph {
00052 
00062     template <typename T>
00063 class DynSlist : public Slist<T>
00064 {
00065 
00066 private:
00067 
00068   size_t num_items;
00069   int        current_pos;
00070   Snode<T> * current_node;
00071   typename Slist<T>::Node * get_previous_to_pos(const int & pos)
00072   {
00073 
00074     if (pos > num_items)
00075       throw std::out_of_range ("position out of range");
00076 
00077     if (pos < current_pos) // hay que retroceder?
00078       { // Si, reinicie posición actual
00079         current_pos  = 0;
00080         current_node = this;
00081       }
00082     
00083     while (current_pos < pos)  // avanzar hasta nodo predecesor a pos
00084       {
00085         current_node = current_node->get_next();
00086         ++current_pos;
00087       }
00088 
00089     return current_node;
00090   }
00091 
00092 public:
00093 
00095   DynSlist() : num_items(0), current_pos(0), current_node(this)
00096   { 
00097     // Empty 
00098   } 
00114   T & operator [] (const size_t & i) 
00115 
00116     throw(std::exception, std::out_of_range)
00117 
00118   {
00119     return get_previous_to_pos(i)->get_next()->get_data();
00120   }    
00121 
00123   size_t size() const { return num_items; }
00124 
00125 
00137   void insert(const int & pos, const T & data) 
00138 
00139     throw(std::exception, std::bad_alloc, std::out_of_range)
00140 
00141   {
00142         // apartar nodo para nuevo elemento
00143     typename Slist<T>::Node * node = new typename Slist<T>::Node (data);
00144 
00145         // obtener nodo predecesor al nuevo elemento
00146     typename Slist<T>::Node * prev = get_previous_to_pos(pos);
00147     
00148     prev->insert_next(node);
00149     ++num_items;
00150   }
00151 
00157   void remove(const int & pos) 
00158 
00159     throw(std::exception, std::range_error)
00160 
00161   {
00162         // obtener nodo predecesor al nuevo elemento
00163     typename Slist<T>::Node * prev = get_previous_to_pos(pos);
00164 
00165     typename Slist<T>::Node * node_to_delete = prev->remove_next();
00166 
00167     delete node_to_delete;
00168 
00169     --num_items;
00170   }
00171 
00173   ~DynSlist() 
00174   {
00175         // eliminar nodo por nodo hasta que la lista devenga vacía
00176     while (not this->is_empty())
00177       delete this->remove_first(); // remove_first de la clase base Slink
00178   }
00184   struct Iterator : public Slist<T>::Iterator
00185   {
00187     Iterator(DynSlist & list) : Slist<T>::Iterator(list) { /* Empty */ }
00188 
00190     T & get_current() { return Slist<T>::Iterator::get_current()->get_data(); }
00191   };
00192 
00193 };
00194 
00195 } // end namespace Aleph
00196 
00197 # endif // TPL_DYNSLIST_H
00198 

Leandro R. León