Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

ixlib_ring_queue.hh

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 //  Description      : Ring queue container
00003 // ----------------------------------------------------------------------------
00004 //  (c) Copyright 1999 by iXiONmedia, all rights reserved.
00005 // ----------------------------------------------------------------------------
00006 
00007 
00008 
00009 
00010 #ifndef IXLIB_RING_QUEUE
00011 #define IXLIB_RING_QUEUE
00012 
00013 
00014 
00015 
00016 #include <ixlib_numeric.hh>
00017 #include <ixlib_array.hh>
00018 
00019 
00020 
00021 
00022 namespace ixion {
00032   template<class T,class Allocator = std::allocator<T> >
00033   class ring_queue {
00034     private:
00035       auto_array<T,Allocator>           Data;
00036       TIndex                            Head;
00037       TIndex                            Tail;
00038     
00039     public:
00040       ring_queue(TIndex capacity = 0)
00041         : Data(capacity),Head(0),Tail(0) {
00042         }
00043       
00045       TSize capacity() const {
00046         return Data.capacity();
00047         }
00048       
00050       TSize size() const {
00051         return NUM_CIRCLEDIST(Head,Tail,Data.capacity());
00052         }
00053       
00055 
00059       inline TSize pop(T *data,TSize maxcount = 1);
00060       
00062       inline void push(T *data,TSize count = 1);
00063       
00065 
00068       inline T *popPointer(TSize &maxcount);
00069       
00071       inline void popPointerCommit(TSize count);
00072 
00074 
00078       inline T *pushPointer(TSize &maxcount);
00079       
00081       inline void pushPointerCommit(TSize count);
00082       
00084       inline void allocate(TSize capacity) {
00085         Data.allocate(capacity);
00086         Head = 0;
00087         Tail = 0;
00088         }
00089     };
00090   }
00091 
00092 
00093 
00094 
00095 template<class T,class Allocator>
00096 ixion::TSize ixion::ring_queue<T,Allocator>::pop(T *data,TSize maxcount) {
00097   while (count) {
00098     TSize loopmax;
00099     T *buffer = popPointer(loopmax);
00100     if (loopmax == 0)
00101       EXGEN_THROW(EC_BUFFERUNDERFLOW)
00102     
00103     TSize countdown = loopmax;
00104     while (countdown--)
00105       *data++ = *buffer++;
00106 
00107     popPointerCommit(loopmax);
00108     count -= loopmax;
00109     }
00110   }
00111 
00112 
00113 
00114 
00115 template<class T,class Allocator>
00116 void ixion::ring_queue<T,Allocator>::push(T *data,TSize count) {
00117   TSize result = 0;
00118   while (count) {
00119     TSize loopmax;
00120     T *buffer = pushPointer(loopmax);
00121     if (loopmax == 0) break;
00122     
00123     TSize countdown = loopmax;
00124     while (countdown--)
00125       *buffer++ = *data++;
00126 
00127     pushPointerCommit(loopmax);
00128     count -= loopmax;
00129     result += loopmax;
00130     }
00131   return result;
00132   }
00133 
00134 
00135 
00136 
00137 template<class T,class Allocator>
00138 T *ixion::ring_queue<T,Allocator>::popPointer(TSize &maxcount) {
00139   if (Tail <= Head)
00140     maxcount = Head-Tail;
00141   else
00142     maxcount = Data.capacity() - Tail;
00143   return Data+Tail;
00144   }
00145 
00146 
00147 
00148 
00149 template<class T,class Allocator>
00150 void ixion::ring_queue<T,Allocator>::popPointerCommit(TSize count) {
00151   Tail = (Tail+count) % Data.capacity();
00152   }
00153 
00154 
00155 
00156 
00157 template<class T,class Allocator>
00158 T *ixion::ring_queue<T,Allocator>::pushPointer(TSize &maxcount) {
00159   if (Tail <= Head) {
00160     maxcount = Data.capacity() - Head;
00161     if (Tail == 0 && maxcount > 0) maxcount--;
00162     }
00163   else
00164     // we may not fill the buffer entirely, as head == tail means "empty"!
00165     maxcount = Tail - Head - 1;
00166   return Data+Head;
00167   }
00168 
00169 
00170 
00171 
00172 template<class T,class Allocator>
00173 void ixion::ring_queue<T,Allocator>::pushPointerCommit(TSize count) {
00174   Head = (Head+count) % Data.capacity();
00175   }
00176 
00177 
00178 
00179 
00180 #endif

Generated on Wed Oct 31 17:12:24 2001 for ixlib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001