00001 #ifndef MISC_CBUFFER_H
00002 #define MISC_CBUFFER_H
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
00033 #include <vector>
00034 #include <cassert>
00035
00045 template<class T,class A = std::allocator<T> >
00046 class cbuffer : private std::vector<T,A>
00047 {
00048 private:
00049 typedef typename std::vector<T,A> parent;
00050
00051 public:
00052
00053 typedef typename parent::iterator iterator;
00054 typedef typename parent::const_iterator const_iterator;
00055 typedef typename parent::size_type size_type;
00056
00061 cbuffer(const size_type capacity = 0,const T &def = T())
00062 : _size(0), _full(false)
00063 {
00064 parent::reserve(capacity);
00065 parent::resize(capacity,def);
00066 _begin = _end = parent::begin();
00067 }
00068
00071 ~cbuffer()
00072 {
00073 }
00074
00077 size_type capacity() const
00078 {
00079 return parent::size();
00080 }
00081
00084 size_type size() const
00085 {
00086 return _size;
00087 }
00088
00090 bool empty() const
00091 {
00092 return !_full && _begin==_end;
00093 }
00094
00096 bool full() const
00097 {
00098 return _full;
00099 }
00100
00107 void push_front(const T &x)
00108 {
00109 if (parent::size())
00110 {
00111 decrement(_begin);
00112 *_begin = x;
00113
00114 if (_full)
00115 decrement(_end);
00116 else
00117 {
00118 _size++;
00119 if (_size==parent::size())
00120 _full = true;
00121 }
00122 }
00123 }
00124
00131 void push_back(const T &x)
00132 {
00133 if (parent::size())
00134 {
00135 *_end = x;
00136 increment((iterator &)_end);
00137 if (_full)
00138 increment((iterator &)_begin);
00139 else
00140 {
00141 _size++;
00142 if (_size==parent::size())
00143 _full = true;
00144 }
00145 }
00146 }
00147
00149 void pop_front()
00150 {
00151 assert(parent::size());
00152 assert(_size>0);
00153 if (_size>0)
00154 {
00155 increment((const_iterator &)_begin);
00156 _size--;
00157 _full = false;
00158 }
00159 }
00160
00162 void pop_back()
00163 {
00164 assert(parent::size());
00165 assert(_size>0);
00166 if (_size>0)
00167 {
00168 decrement((iterator &)_end);
00169 _size--;
00170 _full = false;
00171 }
00172 }
00173
00175 T &front()
00176 {
00177 assert(parent::size());
00178 assert(_size>0);
00179 return *_begin;
00180 }
00181
00183 const T &front() const
00184 {
00185 assert(parent::size());
00186 assert(_size>0);
00187 return *_begin;
00188 }
00189
00191 T &back()
00192 {
00193 assert(parent::size());
00194 assert(_size>0);
00195 iterator i=_end;
00196 decrement(i);
00197 return *i;
00198 }
00199
00201 const T &back() const
00202 {
00203 assert(parent::size());
00204 assert(_size>0);
00205 iterator i=_end;
00206 decrement((const_iterator&)i);
00207 return *i;
00208 }
00209
00211 T &operator[](const size_type i)
00212 {
00213 if (_begin<_end)
00214 return *(_begin+i);
00215 else
00216 {
00217 const size_type s1 = parent::end()-_begin;
00218 if (i<s1)
00219 return *(_begin+i);
00220 else
00221 return *(parent::begin()+i-s1);
00222 }
00223 }
00224
00226 const T &operator[](const size_type i) const
00227 {
00228 if (_begin<_end)
00229 return *(_begin+i);
00230 else
00231 {
00232 const size_type s1 = parent::end()-_begin;
00233 if (i<s1)
00234 return *(_begin+i);
00235 else
00236 return *(parent::begin()+i-s1);
00237 }
00238 }
00239
00241 void leftShift()
00242 {
00243 decrement(_begin);
00244 decrement(_end);
00245 }
00246
00248 void rightShift()
00249 {
00250 decrement(_begin);
00251 decrement(_end);
00252 }
00253
00255 void clear()
00256 {
00257 _begin = _end = parent::begin();
00258 _size = 0;
00259 _full = false;
00260 }
00261
00263 void swap(cbuffer<T,A> &buffer)
00264 {
00265 parent::swap(buffer);
00266 std::swap(_begin,buffer._begin);
00267 std::swap(_end ,buffer._end );
00268 std::swap(_size ,buffer._size );
00269 std::swap(_full ,buffer._full );
00270 }
00271
00279 void resize(const size_type cap)
00280 {
00281 if (cap==capacity())
00282 return;
00283
00284 cbuffer<T,A> tmp(cap);
00285 swap(tmp);
00286
00287 iterator i = tmp._begin;
00288 iterator j = _begin;
00289 size_type k=0;
00290
00291 for (; k<cap && k<capacity() && k<tmp.size(); j++,k++)
00292 {
00293 *j = *i;
00294 tmp.increment((const_iterator &)i);
00295 }
00296
00297 _end = j;
00298 _size = k;
00299 _full = (_size==cap);
00300 }
00301
00302 private:
00303
00304 iterator _begin;
00305 iterator _end;
00306 size_type _size;
00307 bool _full;
00308
00310 void increment(const_iterator &i) const
00311 {
00312 i++;
00313 if (i==parent::end())
00314 i = parent::begin();
00315 }
00316
00318 void decrement(const_iterator &i) const
00319 {
00320 if (i==parent::begin())
00321 i += parent::size()-1;
00322 else
00323 i--;
00324 }
00325
00327 void increment(iterator &i)
00328 {
00329 i++;
00330 if (i==parent::end())
00331 i = parent::begin();
00332 }
00333
00335 void decrement(iterator &i)
00336 {
00337 if (i==parent::begin())
00338 i += parent::size()-1;
00339 else
00340 i--;
00341 }
00342 };
00343
00344 #endif
00345