00001
00002
00003
00004
00005
00006
00007
00008 #ifndef QAF_UTIL_CONTAINER_H
00009 #define QAF_UTIL_CONTAINER_H
00010
00011 #include <math.h>
00012 #include <stdexcept>
00013 #include <stdlib.h>
00014
00015
00016 namespace qaf {
00017
00041 template <typename T>
00042 class Container {
00043 public:
00047 Container () {
00048
00049 count = 0;
00050
00051
00052 capacity = 1;
00053 data = new T[1];
00054 }
00055
00059 Container ( const T * elems, int _count ) {
00060 count = _count;
00061 capacity = _count;
00062 data = new T[count];
00063
00064 for ( int i = 0; i < count; i++ )
00065 data[i] = elems[i];
00066 }
00067
00072 Container ( const Container & orig ) {
00073 count = orig.count;
00074 capacity = orig.capacity;
00075 data = new T[capacity];
00076
00077 for ( int i = 0; i < count; i++ )
00078 data[i] = orig.data[i];
00079 }
00080
00084 inline Container & operator = ( const Container & other ) {
00085 reserve( other.count );
00086
00087 for ( int i = 0; i < other.count; i++ )
00088 data[i] = other.data[i];
00089
00090 count = other.count;
00091
00092 return (*this);
00093 }
00094
00095
00100 inline void add ( const T & elem ) {
00101
00102 reserve( count + 1 );
00103
00104
00105 data[count] = elem;
00106
00107 count++;
00108 }
00109
00119 inline void add ( int index, const T & elem ) {
00120
00121 if ( index < 0 || index > count )
00122 throw std::out_of_range("Container index out of range");
00123
00124
00125 reserve( count + 1 );
00126
00127
00128 for ( int i = count; i > index; i-- )
00129 data[i] = data[i - 1];
00130
00131
00132 data[index] = elem;
00133 count++;
00134 }
00135
00142 inline int indexOf ( const T & elem ) const {
00143 for ( int i = 0; i < count; i++ )
00144 if ( data[i] == elem )
00145 return i;
00146
00147 return -1;
00148 }
00149
00159 inline void remove ( int index ) {
00160
00161 if ( index < 0 || index >= count )
00162 throw std::out_of_range("Container index out of range");
00163
00164
00165 for ( int i = index; i < count - 1; i++ )
00166 data[i] = data[i + 1];
00167
00168
00169 count--;
00170 }
00171
00178 inline bool removeFirst ( const T & elem ) {
00179 int index = indexOf( elem );
00180
00181 if ( index == -1 )
00182 return false;
00183 else {
00184 remove( index );
00185 return true;
00186 }
00187 }
00188
00195 inline bool removeAll ( const T & elem ) {
00196 bool foundIt = false;
00197
00198 for ( int i = count - 1; i >= 0; i-- ) {
00199 if ( data[i] == elem ) {
00200 remove( i );
00201 foundIt = true;
00202 }
00203 }
00204
00205 return foundIt;
00206 }
00207
00211 inline void removeAll () {
00212 count = 0;
00213 }
00214
00218 inline int getCount () const {
00219 return count;
00220 }
00221
00232 inline const T & operator[] ( int index ) const {
00233
00234 if ( index < 0 || index >= count )
00235 throw std::out_of_range("Container index out of range");
00236
00237 return data[index];
00238 }
00239
00250 inline T & operator[] ( int index ) {
00251
00252 if ( index < 0 || index >= count )
00253 throw std::out_of_range("Container index out of range");
00254
00255 return data[index];
00256 }
00257
00262 inline const T & elem ( int index ) const {
00263 return operator[]( index );
00264 }
00265
00270 inline T & elem ( int index ) {
00271 return operator[]( index );
00272 }
00273
00278 inline const T & tail () const {
00279 return operator[]( count - 1 );
00280 }
00281
00282
00287 inline T & tail () {
00288 return operator[]( count - 1 );
00289 }
00290
00291
00298 inline const T * getData () const {
00299 return data;
00300 }
00301
00311 inline void toBeginning ( int index ) {
00312
00313 if ( index < 0 || index >= count )
00314 throw std::out_of_range("Container index out of range");
00315
00316
00317 if ( index == 0 )
00318 return;
00319
00320
00321 T elem = data[index];
00322
00323
00324 for ( int i = index; i >= 1; i-- )
00325 data[i] = data[i - 1];
00326
00327
00328 data[0] = elem;
00329 }
00330
00340 inline void toEnd ( int index ) {
00341
00342 if ( index < 0 || index >= count )
00343 throw std::out_of_range("Container index out of range");
00344
00345
00346 if ( index == count - 1 )
00347 return;
00348
00349
00350 T elem = data[index];
00351
00352
00353 for ( int i = index + 1; i < count; i++ )
00354 data[i - 1] = data[i];
00355
00356
00357 data[count - 1] = elem;
00358 }
00359
00364 inline void swap ( int i, int j ) {
00365
00366 if ( i < 0 || i >= count ||
00367 j < 0 || j >= count )
00368 throw std::out_of_range("Container index out of range");
00369
00370
00371 if ( i == j )
00372 return;
00373
00374 T tmp = data[j];
00375 data[j] = data[i];
00376 data[i] = tmp;
00377 }
00378
00379
00383 virtual ~Container () {
00384 delete[] data;
00385 }
00386
00387 private:
00388 T * data;
00389 int capacity;
00390 int count;
00391
00392
00393 void reserve ( int size ) {
00394 if ( capacity < size ) {
00395
00396 do {
00397 capacity = (int) ceil( capacity * 1.25 );
00398 } while ( capacity < size );
00399
00400
00401 T * newData = new T[capacity];
00402
00403
00404 for ( int i = 0; i < count; i++ )
00405 newData[i] = data[i];
00406
00407
00408 delete[] data;
00409 data = newData;
00410 }
00411 }
00412 };
00413
00414 }
00415
00416 #endif