tpl_arrayQueue.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_ARRAYQUEUE_H
00045 # define TPL_ARRAYQUEUE_H
00046 
00047 # include <ahAssert.H>
00048 # include <ahDefs.H>
00049 
00050 using namespace Aleph;
00051 
00052 namespace Aleph {
00053 
00078     template <typename T> 
00079 class ArrayQueue
00080 {
00081 
00082 private:
00083 
00084   const size_t two_pow;
00085 
00086   const size_t dim;
00087 
00088   T * array;
00089   size_t front_index; /* index of oldest inserted item */
00090   size_t rear_index;
00091   const size_t mask;
00092   size_t num_items; 
00093 
00094   void increase_index(size_t & i, const size_t & inc = 1) const
00095   {
00096 
00097     I( ((i + inc)%dim) == ((i+ inc)&mask) );
00098 
00099     i += inc;
00100     i &= mask;  
00101   }
00102   T & rear_item(const size_t & i = 0) 
00103   {
00104 
00105     I(static_cast<size_t>((rear_index - i - 1) & mask) == 
00106            (rear_index - i - 1)%dim);
00107 
00108     return array[static_cast<size_t> ((rear_index - i - 1) & mask)];
00109   }
00110 
00111 public:
00112 
00113 
00122   ArrayQueue(const size_t & tp = 8) 
00123     : two_pow(tp), dim(1<<two_pow), array(NULL), front_index(0), 
00124       rear_index(0), mask(dim - 1), num_items(0)
00125   {
00126     array = new T [dim];
00127   }
00128 
00130   ~ArrayQueue()
00131   {
00132     if (array != NULL)
00133       delete [] array;
00134   }
00135 
00144   T & put(const T & item) throw(std::exception,std::overflow_error)
00145   {
00146 
00147     if (num_items >= dim)
00148       throw std::overflow_error ("Array queue is full");
00149 
00150     array[rear_index] = item;
00151     T & ret_val = array[rear_index];
00152     increase_index(rear_index);
00153     num_items++;
00154     return ret_val;
00155   }
00172   T & putn(const size_t & n) throw(std::exception, std::overflow_error)
00173   {
00174 
00175     if (num_items + n >= dim)
00176       throw std::overflow_error ("Array queue is full");
00177 
00178     increase_index(rear_index, n);
00179     num_items += n;
00180 
00181     return rear_item();
00182   }
00191   T get() throw(std::exception, std::underflow_error)
00192   {
00193 
00194     if (num_items == 0)
00195       throw std::underflow_error ("queue is empty");
00196 
00197     num_items--;
00198     T ret_val = array[front_index]; 
00199     increase_index(front_index);
00200 
00201     return ret_val;
00202   }
00213   T & getn(const size_t & n) throw(std::exception, std::underflow_error)
00214   {
00215 
00216     if (num_items < n)
00217       throw std::underflow_error ("queue is empty");
00218 
00219     num_items -= n;
00220     increase_index(front_index, n);
00221     return array[front_index];
00222   } 
00233   T & front(const size_t & i = 0) throw(std::exception, std::underflow_error)
00234   {
00235     if (i >= num_items) 
00236       throw std::underflow_error ("queue is empty");
00237     return array[front_index + i];
00238   }
00249   T & rear(const size_t & i = 0) throw(std::exception, std::underflow_error)
00250   {
00251     if (i >= num_items) 
00252       throw std::underflow_error ("queue is empty");
00253     return rear_item(i);
00254   }
00255 
00257   const size_t & size() const { return num_items; }
00258 
00260   bool is_empty() const { return num_items == 0; }
00261 
00264   const size_t & capacity() const { return dim; }
00265 };
00266 
00289     template <typename T> 
00290 class FixedQueue
00291 {
00292 
00293 private:
00294 
00295   const size_t two_pow;
00296 
00297   const size_t dim;
00298 
00299   T * array;
00300   size_t front_index; /* index of oldest inserted item */
00301   size_t rear_index;
00302   const size_t mask;
00303   size_t num_items; 
00304   void increase_index(size_t & i, const size_t & inc = 1) const
00305   {
00306 
00307     I( ((i + inc)%dim) == ((i+ inc)&mask) );
00308 
00309     i += inc;
00310     i &= mask;  
00311   }
00312   T & rear_item(const size_t & i = 0) 
00313   {
00314 
00315     I(static_cast<size_t>((rear_index - i - 1) & mask) == 
00316            (rear_index - i - 1)%dim);
00317 
00318     return array[static_cast<size_t> ((rear_index - i - 1) & mask)];
00319   }
00320 
00321 public:
00322 
00330   FixedQueue(const size_t & tp = 8)  
00331     : two_pow(tp), dim(1<<two_pow), array(NULL), front_index(0), 
00332       rear_index(0), mask(dim - 1), num_items(0)
00333   { 
00334     array = new T [dim];
00335   }
00336 
00338   ~FixedQueue()
00339   {
00340     if (array != NULL)
00341       delete [] array;
00342   }
00343 
00351   T & put(const T& item) throw(std::exception, std::overflow_error)
00352   {
00353     I(num_items < dim);
00354     array[rear_index] = item;
00355     T & ret_val = array[rear_index];
00356     increase_index(rear_index);
00357     num_items++;
00358     return ret_val;
00359   }
00360 
00375   T & putn(const size_t & n) throw(std::exception, std::overflow_error)
00376   {
00377     I(num_items + n < dim);
00378     increase_index(rear_index, n);
00379     num_items += n;
00380 
00381     return rear_item();
00382   }
00383 
00391   T get() throw(std::exception, std::underflow_error)
00392   {
00393     I(num_items > 0);
00394     num_items--;
00395     T ret_val = array[front_index]; 
00396     increase_index(front_index);
00397 
00398     return ret_val;
00399   }
00400 
00410   T & getn(const size_t & n) throw(std::exception, std::underflow_error)
00411   {
00412     I(num_items >= n);
00413     num_items -= n;
00414     increase_index(front_index, n);
00415     return array[front_index];
00416   } 
00417 
00428   T & front(const size_t & i = 0) throw(std::exception, std::underflow_error)
00429   {
00430     I(i < num_items);
00431     return array[front_index + i];
00432   }
00433 
00443   T & rear(const size_t & i = 0) throw(std::exception, std::underflow_error)
00444   {
00445     I(i < num_items);
00446     return rear_item(i);
00447   }
00449   const size_t & size() const { return num_items; }
00450 
00452   bool is_empty() const { return num_items == 0; }
00453 
00456   const size_t & capacity() const { return dim; }
00457 };
00458 
00459 } // end namespace Aleph
00460 
00461 # endif /* TPL_ARRAYQUEUE_H */
00462 

Leandro R. León