00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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;
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;
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 }
00460
00461 # endif
00462