DynamicArray.h

00001 // $Id: DynamicArray.h 21 2010-09-05 04:18:17Z cschwarz1 $
00002 
00003 #ifndef BASE_DYNAMICARRAY_H
00004 #define BASE_DYNAMICARRAY_H
00005 
00006 #include <cstdio>   // sprintf
00007 #include <stdexcept>
00008 
00009 namespace base {
00011 
00015     template<class T> class DynamicArray {
00016     public:
00018         typedef size_t size_type;
00019 
00021         DynamicArray() {
00022             _array = NULL;
00023             _size = _used = 0;
00024         }
00025 
00027         DynamicArray(const DynamicArray<T> &src) {
00028             _array = NULL;
00029             _size = _used = 0;
00030             *this = src;
00031         }
00032 
00033         ~DynamicArray() {
00034             if (_array)
00035                 free(_array);
00036         }
00037 
00039 
00042         void add(T item) {
00043             if (_used >= _size) {
00044                 T         *array;
00045                 size_type  newsize;
00046 
00047                 newsize = _used + 16;
00048                 array = static_cast<T*>(_array ? realloc(_array, newsize * sizeof(T)) : malloc(newsize * sizeof(T)));
00049                 if (!array)
00050                     throw std::bad_alloc();
00051                 _array = array;
00052                 _size = newsize;
00053             }
00054             _array[_used++] = item;
00055         }
00056 
00058         void clear() {
00059             _used = 0;
00060         }
00061 
00063 
00066         T *data() const {
00067             return _array;
00068         }
00069 
00071 
00074         bool empty() const {
00075             return !_used;
00076         }
00077 
00079 
00083         void erase(size_type pos, size_type count = 1) {
00084             if (pos < _used) {
00085                 if (pos + count > _used)
00086                     count = _used - pos;
00087                 if (count) {
00088                     if (pos + count < _used)
00089                         memmove(_array + pos, _array + pos + count, (_used - (pos + count)) * sizeof(T));
00090                     _used -= count;
00091                 }
00092             }
00093         }
00094 
00096 
00099         T get(size_type pos) const {
00100             if (!_array || pos >= _used) {
00101                 char msg[64];
00102 
00103                 sprintf(msg, "DynamicArray index out of range: %u >= %u", pos, _used);
00104                 throw std::out_of_range(msg);
00105             }
00106             return _array[pos];
00107         }
00108 
00110 
00114         void set(size_type pos, T item) {
00115             if (!_array || pos >= _used) {
00116                 char msg[64];
00117 
00118                 sprintf(msg, "DynamicArray index out of range: %u >= %u", pos, _used);
00119                 throw std::out_of_range(msg);
00120             }
00121             _array[pos] = item;
00122         }
00123 
00125 
00128         size_type size() const {
00129             return _used;
00130         }
00131 
00133 
00136         T operator[](size_type pos) const {
00137             return get(pos);
00138         }
00139 
00141 
00144         T &operator[](size_type pos) {
00145             if (!_array || pos >= _used) {
00146                 char msg[64];
00147 
00148                 sprintf(msg, "DynamicArray index out of range: %u >= %u", pos, _used);
00149                 throw std::out_of_range(msg);
00150             }
00151             return _array[pos];
00152         }
00153 
00155         DynamicArray<T> &operator=(const DynamicArray<T> &src) {
00156             T         *newdata;
00157             size_type  newsize;
00158 
00159             newdata = src.data();
00160             newsize = src.size();
00161             if (newsize > _size) {
00162                 T *array;
00163 
00164                 array = static_cast<T*>(_array ? realloc(_array, newsize * sizeof(T)) : malloc(newsize * sizeof(T)));
00165                 if (!array)
00166                     throw std::bad_alloc();
00167                 _array = array;
00168                 _size = newsize;
00169             }
00170             for (_used = 0; _used < size; _used++)
00171                 _array[_used] = newdata[_used];
00172             return *this;
00173         }
00174 
00175     private:
00176         T         *_array; 
00177         size_type  _size;  
00178         size_type  _used;  
00179     };
00180 }
00181 
00182 #endif