Main Page | Class List | File List | Class Members

BoundedQueue.hpp

00001 /*
00002  * Copyright (C) 2003-2004
00003  * Slawomir Lisznianski <slisznianski@asyncnet.com>
00004  *
00005  * Permission to use, copy, modify, distribute and sell this software
00006  * and its documentation for any purpose is hereby granted without fee,
00007  * provided that the above copyright notice appear in all copies and
00008  * that both that copyright notice and this permission notice appear
00009  * in supporting documentation. Slawomir Lisznianski makes no
00010  * representations about the suitability of this software for any
00011  * purpose. It is provided "as is" without express or implied warranty.
00012  *
00013  */
00014 
00015 #ifndef RHA_BOUNDEDQUEUE_HPP
00016 #define RHA_BOUNDEDQUEUE_HPP
00017 
00018 #include <stdexcept>
00019 #include <deque>
00020 
00021 namespace Rha
00022 {
00028     struct QueueOverflowError :
00029       public std::runtime_error
00030     {
00031       QueueOverflowError() :
00032         std::runtime_error("queue overflow error")
00033       {}
00034     };
00035 
00050     template<class T,
00051              class C = std::deque<T> >
00052     class BoundedQueue
00053     {
00054     public:
00055       typedef BoundedQueue<T, C> OfType;
00056       typedef T                  Task;
00057       typedef C                  Container;
00058 
00068       class Configurator
00069       {
00070       public:
00071         // Default values.
00072         // VC++ 6 doesn't support in-place initialization of static const
00073         // per C2258 and C225.
00074         //
00075         enum Defaults {defaultUpperBound = 1000} ;
00076 
00082         Configurator()
00083         {
00084           init__();
00085         }
00086 
00092         unsigned int upperBound() const
00093         {
00094           return M_upperBound;
00095         }
00096 
00102         Configurator& upperBound(unsigned int limit)
00103         {
00104           M_upperBound = limit;
00105           return (*this);
00106         }
00107 
00108       private:
00109         void init__()
00110         {
00111           // Defaults.
00112           //
00113           M_upperBound = defaultUpperBound;
00114         }
00115 
00116         unsigned int M_upperBound;
00117       };
00118 
00120       BoundedQueue();
00121 
00128       BoundedQueue(const OfType& queue);
00129 
00136       BoundedQueue(const Configurator& config);
00137 
00143       ~BoundedQueue();
00144 
00150       inline void setUp();
00151 
00157       inline bool empty() const;
00158 
00164       inline bool full() const;
00165 
00171       inline void flush();
00172 
00177       inline Task& front();
00178       inline const Task& front() const;
00179 
00184       inline void push(const Task& val);
00185 
00190       inline void pop();
00191     private:
00192       Configurator  M_configurator;
00193       Container M_container;
00194     };
00195 }
00196 
00197 template<class T,
00198          class C>
00199 Rha::BoundedQueue<T,
00200                   C>::BoundedQueue()
00201 { }
00202 
00203 template<class T,
00204          class C>
00205 Rha::BoundedQueue<T,
00206                   C>::BoundedQueue(const OfType& queue) :
00207   M_configurator(queue.M_configurator), M_container(queue.M_container)
00208 { }
00209 
00210 template<class T,
00211          class C>
00212 Rha::BoundedQueue<T,
00213                   C>::BoundedQueue(const Configurator& configurator) :
00214   M_configurator(configurator)
00215 { }
00216 
00217 template<class T,
00218          class C>
00219 Rha::BoundedQueue<T,
00220                   C>::~BoundedQueue()
00221 { }
00222 
00223 template<class T,
00224          class C>
00225 void
00226 Rha::BoundedQueue<T,
00227                   C>::setUp()
00228 { }
00229 
00230 template<class T,
00231          class C>
00232 bool
00233 Rha::BoundedQueue<T,
00234                   C>::empty() const
00235 {
00236   return (M_container.empty());
00237 }
00238 
00239 template<class T,
00240          class C>
00241 bool
00242 Rha::BoundedQueue<T,
00243                   C>::full() const
00244 {
00245   return !(M_configurator.upperBound() > M_container.size());
00246 }
00247 
00248 template<class T,
00249          class C>
00250 void
00251 Rha::BoundedQueue<T,
00252                   C>::flush()
00253 {
00254   M_container.clear();
00255 }
00256 
00257 template<class T,
00258          class C>
00259 typename Rha::BoundedQueue<T,
00260                              C>::Task&
00261 Rha::BoundedQueue<T,
00262                   C>::front()
00263 {
00264   return (M_container.front());
00265 }
00266 
00267 template<class T,
00268          class C>
00269 const typename Rha::BoundedQueue<T,
00270                                    C>::Task&
00271 Rha::BoundedQueue<T,
00272                   C>::front() const
00273 {
00274   return (M_container.front());
00275 }
00276 
00277 template<class T,
00278          class C>
00279 void
00280 Rha::BoundedQueue<T,
00281                   C>::push(const Task& val)
00282 {
00283   if (!full())
00284     M_container.push_back(val);
00285   else
00286     throw QueueOverflowError();
00287 }
00288 
00289 template<class T,
00290          class C>
00291 void
00292 Rha::BoundedQueue<T,
00293                   C>::pop()
00294 {
00295   M_container.pop_front();
00296 }
00297 
00298 #endif // RHA_BOUNDEDQUEUE_HPP