00001
00002 #ifndef _GROWABLEARRAY_H_
00003 #define _GROWABLEARRAY_H_
00004
00005 #include <stdexcept>
00006
00075 template <class T>
00076 class GrowableArray {
00077 private:
00078 typedef enum { StartArraySize = 64 } bogus;
00079 size_t num_elem;
00080 size_t array_size;
00081 T *pArray;
00082
00083 private:
00089 bool twice()
00090 {
00091 bool rslt;
00092
00093 T *old_array = pArray;
00094 size_t new_size = array_size * 2;
00095
00096 pArray = new T [ new_size ];
00097 if (pArray != 0) {
00098 rslt = true;
00099 for (int i = 0; i < array_size; i++) {
00100 pArray[i] = old_array[i];
00101 }
00102
00103 delete [] old_array;
00104
00105 array_size = new_size;
00106 }
00107 else {
00108 rslt = false;
00109 }
00110
00111 return rslt;
00112 }
00113
00114
00115 void init(size_t initialSize )
00116 {
00117 array_size = StartArraySize;
00118 while (initialSize > array_size) {
00119 array_size = array_size * 2;
00120 }
00121 pArray = new T[ array_size ];
00122 num_elem = initialSize;
00123 }
00124
00125 public:
00126 GrowableArray()
00127 {
00128 init( 0 );
00129 }
00130
00131
00132 GrowableArray(size_t initialSize)
00133 {
00134 init( initialSize );
00135 }
00136
00137 ~GrowableArray()
00138 {
00139 if (pArray != 0) {
00140 delete [] pArray;
00141 }
00142 }
00143
00144 const size_t length(void) const { return num_elem; }
00145
00146 T &operator[](const size_t i)
00147 throw(std::out_of_range)
00148 {
00149 if (i >= num_elem) {
00150 const char *errMsg = "1. GrowableArray::[] - index out of bounds";
00151 throw std::out_of_range(errMsg);
00152 }
00153 return pArray[ i ];
00154 }
00155
00156 T operator[](const size_t i ) const
00157 throw(std::out_of_range)
00158 {
00159 if (i >= num_elem) {
00160 const char *errMsg = "2. GrowableArray::[] - index out of bounds";
00161 throw std::out_of_range(errMsg);
00162 }
00163 return pArray[ i ];
00164 }
00165
00166 const T *getData() const { return pArray; }
00167
00169 void append( T item )
00170 throw(std::runtime_error)
00171 {
00172
00173 if (num_elem == array_size) {
00174 bool allocOK = twice();
00175 if (!allocOK) {
00176 const char *errMsg = "GrowableArray::append - memory allocation error";
00177 throw std::runtime_error( errMsg );
00178 }
00179 }
00180
00181 pArray[ num_elem ] = item;
00182 num_elem++;
00183 }
00184
00185
00200 void expand( size_t amount )
00201 throw(std::runtime_error)
00202 {
00203 bool allocOK = true;
00204
00205 while (allocOK && num_elem + amount >= array_size) {
00206 allocOK = twice();
00207 if (!allocOK) {
00208 const char *errMsg = "GrowableArray::expand - memory allocation error";
00209 throw std::runtime_error( errMsg );
00210 }
00211 }
00212 num_elem += amount;
00213 }
00214
00215
00217 void remove(void)
00218 {
00219 if (num_elem > 0)
00220 num_elem--;
00221 }
00222
00229 void set_size( size_t new_size )
00230 {
00231 if (new_size <= array_size) {
00232 num_elem = new_size;
00233 }
00234 else {
00235 size_t num_new_elem = new_size - num_elem;
00236 expand( num_new_elem );
00237 }
00238 }
00239
00240 };
00241
00242
00243 #endif