00001
00002
00003 #ifndef BASE_DYNAMICARRAY_H
00004 #define BASE_DYNAMICARRAY_H
00005
00006 #include <cstdio>
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