TpArray.h

Go to the documentation of this file.
00001 // $Id: TpArray.h 182 2006-06-07 17:48:14Z bingmann $
00002 
00003 #ifndef VGS_TpArray_H
00004 #define VGS_TpArray_H
00005 
00006 #include <stdlib.h>
00007 #include <assert.h>
00008 
00009 namespace VGServer {
00010 
00015 template <typename Tp>
00016 class TpArray
00017 {
00018 public:
00019     // *** STL-like typedefs
00020 
00022     typedef TpArray<Tp> tparray;
00023 
00025     typedef Tp value_type;
00026 
00028     typedef value_type& reference;
00029 
00031     typedef const value_type& const_reference;
00032 
00034     typedef value_type* pointer;
00035 
00037     typedef const value_type const_pointer;
00038 
00040     typedef Tp* iterator;
00041 
00043     typedef const Tp* const_iterator;
00044 
00046     typedef unsigned int size_type;
00047 
00048 private:
00050     Tp*         _begin;
00051 
00053     Tp*         _end;
00054 
00056     Tp*         _finish;
00057 
00058 public:
00060     inline TpArray()
00061         : _begin(NULL), _end(NULL), _finish(NULL)
00062     {
00063     }
00064 
00066     explicit inline TpArray(size_type _reserve)
00067         : _begin(NULL), _end(NULL), _finish(NULL)
00068     {
00069         if (_reserve) reserve(0);
00070     }
00071     
00073     inline TpArray(const tparray &other)
00074         : _begin(NULL), _end(NULL), _finish(NULL)
00075     {
00076         reserve(other.size());
00077         iterator i = begin();
00078         for(const_iterator o = other.begin(); o != other.end(); o++, i++) {
00079             // reads: create a new object at the position i within our array by
00080             // copy-constructing a Tp object from the other array.
00081             new (i) value_type (*o);
00082         }
00083         set_size(other.size());
00084     }
00085 
00087     inline ~TpArray()
00088     {
00089         clear();
00090         if (_begin)
00091         {
00092             free(_begin);
00093             _begin = NULL;
00094         }
00095     }
00096 
00099     inline tparray& operator= (const tparray& other)
00100     {
00101         if (*this != other)
00102         {
00103             clear();
00104             reserve(other.size());
00105             iterator i = begin();
00106             for(const_iterator o = other.begin(); o != other.end(); o++, i++) {
00107                 // reads: create a new object at the position i within our array by
00108                 // copy-constructing a Tp object from the other array.
00109                 new (i) value_type (*o);
00110             }
00111             set_size(other.size());
00112         }
00113         return *this;
00114     }
00115 
00118     inline size_type capacity() const
00119     { return size_type(_finish - _begin); }
00120     
00122     inline size_type size() const
00123     { return size_type(_end - _begin); }
00124 
00126     inline bool empty() const
00127     { return begin() == end(); }
00128 
00131     inline void reserve(size_type n)
00132     {
00133         if (capacity() < n)
00134         {
00135             size_type used = size();
00136             
00137             // calculate a new capacity
00138             size_type newcap = capacity();
00139             while(newcap < n) {
00140                 if (newcap < 512) newcap = 512;
00141                 else if (newcap < 1024*1024) newcap = 2 * newcap;
00142                 else newcap += 1024*1024;
00143             }
00144 
00145             // reallocate memory and set new pointers
00146             _begin = static_cast<Tp*>(realloc(_begin, newcap * sizeof(Tp)));
00147             _end = _begin + used;
00148             _finish = _begin + newcap;
00149         }
00150     }
00151 
00153     inline void set_size(size_type n)
00154     { assert(n <= capacity()); _end = _begin + n; }
00155 
00157     inline iterator begin()
00158     { return iterator(_begin); }
00159 
00161     inline const_iterator begin() const
00162     { return const_iterator(_begin); }
00163 
00165     inline iterator end()
00166     { return iterator(_end); }
00167 
00169     inline const_iterator end() const
00170     { return const_iterator(_end); }
00171 
00173     inline void clear()
00174     {
00175         for(iterator i = begin(); i != end(); i++) {
00176             i->~Tp();
00177         }
00178         _end = _begin;
00179     }
00180 
00182     inline reference operator[](size_type n)
00183     { assert(n < size()); return *(begin() + n); }
00184 
00186     inline const_reference operator[](size_type n) const
00187     { assert(n < size()); return *(begin() + n); }
00188 
00190     inline reference last()
00191     { assert(size() > 0); return *(end() - 1); }
00192 
00194     inline const_reference last() const
00195     { assert(size() > 0); return *(end() - 1); }
00196 
00201     inline reference new_back()
00202     {
00203         if (capacity() < size() + 1) reserve(size() + 1);
00204 
00205         pointer newobj = new (_end) value_type();
00206         _end++;
00207         return *newobj;
00208     }
00209 
00213     inline void push_back(const_reference obj)
00214     {
00215         if (capacity() < size() + 1) reserve(size() + 1);
00216 
00217         new (_end) value_type(obj);
00218         _end++;
00219     }
00220 
00222     inline void swap(tparray &other)
00223     {
00224         std::swap(_begin, other._begin);
00225         std::swap(_end, other._end);
00226         std::swap(_finish, other._finish);
00227     }
00228 };
00229 
00230 } // namespace VGServer
00231 
00232 #endif // VGS_TpArray_H

Generated on Wed Sep 27 14:34:00 2006 for VGServer by  doxygen 1.4.7