gml_Queue.h

Go to the documentation of this file.
00001 /** 
00002  *   @file gml_Queue.h
00003  * 
00004  *     Define the gml_TQueue template and the gml_TPointerQueue instance.
00005  * 
00006  *   Copyright (c) 2004 CLIPS-IMAG
00007  * 
00008  *   See the file "gml_LicenseTerms.txt" for information on usage and redistribution
00009  *   of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00010  * 
00011  *   Created in March 2004 (JL).
00012  */
00013 #ifndef __GML_QUEUE__
00014 #define __GML_QUEUE__
00015 
00016 #include "gml/base/gml_Types.h"
00017 #include "gml/base/gml_Errors.h"
00018 #include "gml/base/gml_Array.h"
00019 
00020 
00021 ///
00022 /// gml_TQueue_Base --
00023 ///   Common data to all gml_TQueue instances.
00024 ///
00025 class gml_TQueue_Base
00026 {
00027 public:
00028 
00029   // errors
00030   static gml_TError sErrorQueueFull;    ///< queue is full (occurs on Push)
00031   static gml_TError sErrorQueueEmpty;   ///< queue is empty (occurs on Pop)
00032   
00033   // constants
00034   static UInt32 const sDefaultQueueSize = 64;
00035 
00036 protected:
00037 
00038   // setup
00039   static void ClassInit ();     ///< class setup
00040   static bool sModuleInited;    ///< was ClassInit() called ? 
00041 };
00042 
00043 
00044 
00045 ////////////////////////////////////////////////////////////////////////////////
00046 //                                                                            //
00047 //                         gml_TQueue class declaration                       //
00048 //                                                                            //
00049 ////////////////////////////////////////////////////////////////////////////////
00050 
00051 
00052 ///
00053 /// gml_TQueue --
00054 ///   A template for fixed-length, typed queue (first in, first out) containers.
00055 ///
00056 template <typename T>
00057 class gml_TQueue : public gml_TQueue_Base
00058 {
00059   //
00060   // Instance members
00061   //
00062 
00063 public:  
00064   ///
00065   /// Init --
00066   ///   Allocate resources for a queue of size <queueSize>.
00067   ///
00068   gml_TError Init (UInt32 queueSize = sDefaultQueueSize, gml_TBoolean dropWhenFull = gml_cFalse);
00069   
00070   ///
00071   /// Dispose --
00072   ///   Release resources
00073   ///
00074   void Dispose ();
00075   
00076   ///
00077   /// Push -- 
00078   ///   Push an object into the queue.
00079   ///   Will fail if the queue is full.
00080   ///
00081   gml_TError Push (const T object);
00082   
00083   ///
00084   /// Pop --
00085   ///   Remove the oldest object from the queue and return it in <object>.
00086   ///   Will fail if the queue is empty.
00087   ///
00088   gml_TError Pop  (T & object);
00089   
00090   ///
00091   /// Length --
00092   ///   Return the current queue length (number of items).
00093   ///
00094   UInt32 Length () { return fQueueLength; }
00095   
00096 private:
00097   UInt32        fQueueHead;     ///< index of first item
00098   UInt32        fQueueFree;     ///< index of first free space
00099   UInt32        fQueueSize;     ///< max number of items in queue
00100   UInt32        fQueueLength;   ///< current number of items in queue
00101   gml_TBoolean  fDropWhenFull;  ///< whether to silently drop old elements when pushing into a full queue
00102   gml_TArray<T> fData;          ///< the actual queue data
00103 };
00104 
00105 
00106 ///
00107 /// gml_TPointerQueue --
00108 ///   Queues of pointers, to be used for untyped / polymorphic queues.
00109 ///
00110 class gml_TPointerQueue: public gml_TQueue <gml_TPointer> {};
00111 
00112 
00113 
00114 ///////////////////////////////////////////////////////////////////////////////
00115 //
00116 // Template implementation follows
00117 //
00118 ///////////////////////////////////////////////////////////////////////////////
00119 
00120 
00121 template <typename T>
00122 gml_TError gml_TQueue<T>::Init (UInt32 queueSize, gml_TBoolean dropWhenFull)
00123 {
00124   gml_TError err;
00125   
00126   ClassInit ();
00127   
00128   err = fData.Init (queueSize);
00129   if (err != gml_cNoError) return err;
00130   
00131   fQueueHead    = 0;
00132   fQueueFree    = 0;
00133   fQueueSize    = queueSize;
00134   fQueueLength  = 0;
00135   fDropWhenFull = dropWhenFull;
00136   
00137   return gml_cNoError;
00138 }
00139 
00140 
00141 template <typename T>
00142 void gml_TQueue<T>::Dispose ()
00143 {
00144   fData.Dispose ();
00145   fQueueHead    = 0;
00146   fQueueFree    = 0;
00147   fQueueSize    = 0;
00148   fQueueLength  = 0;
00149   fDropWhenFull = gml_cFalse;
00150 }
00151 
00152 
00153 template <typename T>
00154 gml_TError gml_TQueue<T>::Push (const T object)
00155 {
00156   gml_TError err = gml_cNoError;
00157   
00158   if (fQueueLength >= fQueueSize) {
00159     if (fDropWhenFull) {
00160       T dropped;
00161       gml_TError err = Pop (dropped);
00162       if (err != gml_cNoError) goto exit;
00163     } else {
00164       err = sErrorQueueFull;
00165       goto exit;
00166     }
00167   }
00168 
00169   fData[fQueueFree] = object;
00170   fQueueFree = (fQueueFree + 1) % fQueueSize;
00171   ++fQueueLength;
00172 
00173 exit:
00174   return err;
00175 }
00176 
00177 
00178 template <typename T>
00179 gml_TError gml_TQueue<T>::Pop (T & object)
00180 {
00181   gml_TError err = gml_cNoError;
00182   
00183   if (fQueueLength == 0) {
00184     err = sErrorQueueEmpty;
00185     goto exit;
00186   }
00187     
00188   object = fData[fQueueHead];
00189   fQueueHead = (fQueueHead + 1) % fQueueSize;
00190   --fQueueLength;
00191 
00192 exit:
00193   return err;
00194 }
00195 
00196 #endif /* __GML_QUEUE__ */
00197 
Generated on Tue Jun 12 14:03:27 2007 for gml by Doxygen 1.5.2.