00001
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
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
00080
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
00108
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
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
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 }
00231
00232 #endif // VGS_TpArray_H