Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

misc/cbuffer.h

Go to the documentation of this file.
00001 #ifndef MISC_CBUFFER_H
00002 #define MISC_CBUFFER_H
00003 
00004 /*
00005 
00006   GLT OpenGL C++ Toolkit (LGPL)
00007   Copyright (C) 2000-2002 Nigel Stewart  
00008 
00009   Email: nigels.com@gmail.com   
00010   WWW:   http://www.nigels.com/glt/
00011 
00012   This library is free software; you can redistribute it and/or
00013   modify it under the terms of the GNU Lesser General Public
00014   License as published by the Free Software Foundation; either
00015   version 2.1 of the License, or (at your option) any later version.
00016 
00017   This library is distributed in the hope that it will be useful,
00018   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020   Lesser General Public License for more details.
00021 
00022   You should have received a copy of the GNU Lesser General Public
00023   License along with this library; if not, write to the Free Software
00024   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 

Generated on Tue Nov 5 11:11:04 2002 for GLT by doxygen1.2.18