00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00033 #ifndef S3_RING_BUFFER_H
00034 #define S3_RING_BUFFER_H
00035
00036 #include <s3fc/s3_exception.h>
00037
00043 template<typename T>
00044 class s3_ring_buffer
00045 {
00046
00047
00048
00049
00050 private:
00052 unsigned int capacity;
00053
00055 unsigned int num_of_elems;
00056
00058 T* buffer;
00059
00061 unsigned int buffer_start;
00062 public:
00068 s3_ring_buffer(const unsigned int n_capacity)
00069 : capacity(n_capacity),
00070 num_of_elems(0),
00071 buffer(new T[capacity]),
00072 buffer_start(0)
00073 {
00074 }
00075
00083 s3_ring_buffer(const unsigned int n_capacity, const T& t)
00084 : capacity(n_capacity),
00085 num_of_elems(0),
00086 buffer(new T[capacity]),
00087 buffer_start(0)
00088 {
00089 for (unsigned int i = 0; i < capacity; i++)
00090 {
00091 push_back(t);
00092 }
00093 }
00094
00098 s3_ring_buffer(const s3_ring_buffer& t)
00099 : capacity(t.get_capacity()),
00100 num_of_elems(0),
00101 buffer_start(0)
00102 {
00103
00104 buffer = new T[capacity];
00105
00106 for (unsigned int i = 0; i < t.size(); i++)
00107 {
00108 push_back(t[i]);
00109 }
00110 }
00111
00115 ~s3_ring_buffer()
00116 {
00117 if (buffer)
00118 {
00119 delete [] buffer;
00120 }
00121 }
00122
00128 void push_back(const T& element)
00129 {
00130 buffer[(buffer_start + size()) % capacity] = element;
00131
00132 if ( full() )
00133 {
00134 buffer_start = (buffer_start + 1 ) % capacity;
00135 }
00136 else
00137 {
00138 num_of_elems++;
00139 }
00140 }
00145 unsigned int size() const
00146 {
00147 return num_of_elems;
00148 }
00153 unsigned int get_capacity() const
00154 {
00155 return capacity;
00156 }
00161 bool empty() const
00162 {
00163 return ( size() == 0 );
00164 }
00165
00170 bool full() const
00171 {
00172 return ( size() == capacity );
00173 }
00174
00183 T& operator[](const unsigned int index) const
00184 {
00185 if ( ( size() == 0 ) ||
00186 ( index < 0 ) ||
00187 ( index > size()-1 ) )
00188 {
00189 throw s3_index_exception("s3_ring_buffer::operator[]"
00190 "(const unsigned int index) const",
00191 0, size(), index);
00192 }
00193
00194 return buffer[ (buffer_start + index) % capacity];
00195 }
00196
00205 T& back( void ) const throw( s3_index_exception )
00206 {
00207 if ( empty() )
00208 {
00209 throw s3_index_exception("s3_ring_buffer::back() const",
00210 -1, -1, 0);
00211 }
00212
00213 if ( ! full() )
00214 {
00215 return buffer[ num_of_elems - 1 ];
00216 }
00217 else
00218 {
00219 return buffer[ ( num_of_elems + buffer_start - 1 ) % capacity ];
00220 }
00221
00222
00223 }
00224
00228 s3_ring_buffer& operator=(const s3_ring_buffer& t)
00229 {
00230 if (buffer)
00231 {
00232 delete [] buffer;
00233 }
00234
00235
00236 capacity = t.get_capacity();
00237 num_of_elems = 0;
00238 buffer_start = 0;
00239 buffer = new T[capacity];
00240
00241 for (unsigned int i = 0; i < t.size(); i++)
00242 {
00243 push_back(t[i]);
00244 }
00245
00246 return *this;
00247 }
00248
00254 bool operator==(const s3_ring_buffer& t)
00255 {
00256
00257 if ( t.get_capacity() != get_capacity() )
00258 {
00259 return false;
00260 }
00261
00262 if ( t.size() != size() )
00263 {
00264 return false;
00265 }
00266
00267 for (unsigned int i=0; i < t.size(); i++)
00268 {
00269 if ( t[i] != operator[](i) )
00270 {
00271 return false;
00272 }
00273 }
00274 return true;
00275 }
00276
00277 };
00278
00279 #endif //S3_RING_BUFFER_H