tvector.h
00001 #ifndef _tvector_h
00002 #define _tvector_h
00003
00004 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00005 #include <iostream>
00006 #include <cstdlib>
00007 #ifndef _COREDEBUG_STR
00008 #define _COREDEBUG_STR "To debug the core, use this command:\n"\
00009 " gdb -c core /path/to/executable (gdb) bt"
00010 #endif
00011 #endif
00012
00021 template <class T>
00022 class tvector
00023 {
00024 public:
00026 typedef T* iterator;
00027
00029 typedef const T* const_iterator;
00030
00031 private:
00032 T* x;
00033 unsigned max;
00034 unsigned n;
00035
00036 public:
00038 tvector() {
00039 x = 0;
00040 max = 0;
00041 n = 0;
00042 }
00043
00045 tvector(unsigned n) {
00046
00047
00048 this->n = max = n;
00049 if(n > 0) {
00050 x = new T[n];
00051 fill(begin(), begin() + n, T());
00052 } else {
00053 x = 0;
00054 }
00055 }
00056
00058 tvector(unsigned n, const T& value);
00059
00061 tvector(const tvector& a) {
00062 n = max = a.n;
00063 if(n > 0) {
00064 x = new T[n];
00065 a.copyInto(x);
00066 } else {
00067 x = 0;
00068 }
00069 }
00070
00071 ~tvector() {
00072 if(x != 0) {
00073 delete [] x;
00074 }
00075 }
00076
00078 unsigned size() const {
00079 return n;
00080 }
00081
00083 unsigned capacity() const {
00084 return max;
00085 }
00086
00088 operator T*() {
00089 return x;
00090 }
00091
00093 operator const T*() const {
00094 return x;
00095 }
00096
00098 tvector& operator =(const tvector& a) {
00099 if(n != a.n) {
00100 resize_nofill(a.n);
00101 }
00102 a.copyInto(x);
00103 return *this;
00104 }
00105
00107 void clear() {
00108 delete[] x;
00109 x = 0;
00110 n = max = 0;
00111 }
00112
00114 void erase(iterator first) {
00115 erase(first, first + 1);
00116 }
00117
00119 void erase(iterator first, iterator last);
00120
00122 void erase(const T& x);
00123
00125 void resize(unsigned n) {
00126 resize(n, T());
00127 }
00128
00130 void resize(unsigned n, const T& value) {
00131 unsigned prev = this->n;
00132 resize_nofill(n);
00133 if(this->n > prev) {
00134 fill(begin() + prev, begin() + this->n, value);
00135 }
00136 }
00137
00139 void insert(iterator p, const T& value);
00140
00142 void insert(iterator p, const T* first, const T* last);
00143
00145 void push_back(const T& value) {
00146 if(n < max) {
00147 x[n++] = value;
00148 } else {
00149 resize_nofill(n + 1);
00150 x[n - 1] = value;
00151 }
00152 }
00153
00155 void pop_back() {
00156 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00157 if(n == 0) {
00158 std::cerr << "Fatal error: pop_back() called for empty tvector\n"
00159 _COREDEBUG_STR << std::endl;
00160 ::abort();
00161 }
00162 #endif
00163 --n;
00164 }
00165
00167 T& operator [](int k) {
00168 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00169 if(k < 0 || k >= (int)n) {
00170 std::cerr << "Fatal error: tvector index " << k
00171 << " out of range [0, "
00172 << n << "[\n" _COREDEBUG_STR << std::endl;
00173 ::abort();
00174 }
00175 #endif
00176 return x[k];
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00200 T& front() {
00201 return *begin();
00202 }
00203
00205 const T& front() const {
00206 return *begin();
00207 }
00208
00210 T& back() {
00211 return *(end() - 1);
00212 }
00213
00215 const T& back() const {
00216 return *(end() - 1);
00217 }
00218
00220 iterator begin() {
00221 return x;
00222 }
00223
00225 const_iterator begin() const {
00226 return x;
00227 }
00228
00230 iterator end() {
00231 return x+n;
00232 }
00233
00235 const_iterator end() const {
00236 return x+n;
00237 }
00238
00240 void sort();
00241
00242 private:
00244 void resize_nofill(unsigned _n);
00245
00247 void copyInto(T* y) const {
00248 for(unsigned i = 0; i < n; ++i) {
00249 y[i] = x[i];
00250 }
00251 }
00252
00254 void fill(iterator begin, iterator end, const T& value);
00255
00257 void sort(int lo, int hi);
00258 };
00259
00260 template <class T> tvector<T>::tvector(unsigned _n, const T& value)
00261 {
00262
00263
00264 n = max = _n;
00265 if(n > 0) {
00266 x = new T[n];
00267 fill(begin(), begin() + n, value);
00268 } else {
00269 x = 0;
00270 }
00271 }
00272
00273 template <class T> void tvector<T>::erase(iterator first, iterator last)
00274 {
00275 int d = last - first;
00276 if(d <= 0) {
00277 return;
00278 }
00279 for(unsigned i = last - x; i < n; ++i) {
00280 x[i - d] = x[i];
00281 }
00282 n -= d;
00283 }
00284
00285 template <class T> void tvector<T>::erase(const T& v)
00286 {
00287 for(int i = n - 1; i >= 0; --i) {
00288 if(x[i] == v) {
00289 erase(begin() + i);
00290 }
00291 }
00292 }
00293
00294 template <class T> void tvector<T>::insert(iterator p, const T& value)
00295 {
00296 unsigned k = p - x;
00297 if(n < max) {
00298 for(unsigned i = n; i > k; --i) {
00299 x[i] = x[i - 1];
00300 }
00301 x[k] = value;
00302 } else {
00303 max = 2*(n + 1);
00304 T* y = new T[max];
00305 for(unsigned i = 0; i < k; ++i) {
00306 y[i] = x[i];
00307 }
00308 for(unsigned i = k; i < n; ++i) {
00309 y[i + 1] = x[i];
00310 }
00311 y[k] = value;
00312 delete [] x;
00313 x = y;
00314 }
00315 ++n;
00316 }
00317
00318 template <class T> void tvector<T>::insert(iterator p,
00319 const T* first, const T* last)
00320 {
00321 int delta = last - first + 1;
00322 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00323 if(delta < 1) {
00324 std::cerr << "Fatal error: cannot insert zero or less elements "
00325 "into tvector\n"
00326 _COREDEBUG_STR << std::endl;
00327 ::abort();
00328 }
00329 #endif
00330 int k = p - x;
00331 int k_plus_delta = k + delta;
00332 if(n + delta <= max) {
00333 for(int i = n - 1; i >= k; --i) {
00334 x[i + delta] = x[i];
00335 }
00336 for(int i = k; i < k_plus_delta; ++i) {
00337 x[i] = *(first++);
00338 }
00339 } else {
00340 max = 2*(n + delta);
00341 T* y = new T[max];
00342 for(int i = 0; i < k; ++i) {
00343 y[i] = x[i];
00344 }
00345 for(int i = n - 1; i >= k; --i) {
00346 y[i + delta] = x[i];
00347 }
00348 for(int i = k; i < k_plus_delta; ++i) {
00349 y[i] = *(first++);
00350 }
00351 delete [] x;
00352 x = y;
00353 }
00354 n += delta;
00355 }
00356
00357 template <class T> void tvector<T>::resize_nofill(unsigned _n)
00358 {
00359
00360
00361
00362 if(_n <= max) {
00363 n = _n;
00364 } else {
00365 for(max = 1; max < _n; max <<= 1);
00366 T* y = new T[max];
00367 copyInto(y);
00368 delete [] x;
00369 x = y;
00370 n = _n;
00371 }
00372 }
00373
00374 template <class T> void tvector<T>::fill(iterator p, iterator end, const T& val)
00375 {
00376 while(p != end) {
00377 *(p++) = val;
00378 }
00379 }
00380
00381
00382 template <class T> void tvector<T>::sort()
00383 {
00384 sort(0, n-1);
00385 }
00386
00387
00388 template <class T> void tvector<T>::sort(int lo, int hi)
00389 {
00390 if(lo>=hi) return;
00391 T ref= x[(lo+hi)/2];
00392 int left= lo, right= hi;
00393 while(left <= right) {
00394 while(left < hi && x[left] < ref) left++;
00395 while(right > lo && ref < x[right]) right--;
00396 if(left < right) {
00397 T tmp= x[left];
00398 x[left]= x[right];
00399 x[right]= tmp;
00400 left++; right--;
00401 } else if(left== right) {
00402 left++; right--;
00403 }
00404 }
00405 sort(lo, right);
00406 sort(left, hi);
00407 }
00408
00409 #ifdef DEBUG
00410 template <class T>
00411 inline std::ostream& operator <<(std::ostream& out, const tvector<T>& x)
00412 {
00413 for(unsigned i = 0; i < x.size(); ++i) {
00414 out << x[i];
00415 if(i+1 < x.size() ) {
00416 out << ", ";
00417 }
00418 }
00419 return out;
00420 }
00421 #endif
00422
00423 #endif