DynamicArray.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef _DYNARRAY_H_
00012 #define _DYNARRAY_H_
00013
00014
00015 #if defined(HAVE_R) && !defined(ScalarReal)
00016 #define ScalarReal Rf_ScalarReal
00017 #endif
00018
00019 #include "lib/common.h"
00020 #include "lib/Mathematics.h"
00021 #include "base/SGObject.h"
00022
00023 template <class T> class CDynamicArray;
00024
00032 template <class T> class CDynamicArray : public CSGObject
00033 {
00034 public:
00039 CDynamicArray(int32_t p_resize_granularity=128)
00040 : CSGObject()
00041 {
00042 this->resize_granularity=p_resize_granularity;
00043
00044 array=(T*) calloc(p_resize_granularity, sizeof(T));
00045 ASSERT(array);
00046
00047 num_elements=p_resize_granularity;
00048 last_element_idx=-1;
00049 }
00050
00051 ~CDynamicArray() { free(array); }
00052
00058 inline int32_t set_granularity(int32_t g)
00059 {
00060 g=CMath::max(g,128);
00061 this->resize_granularity = g;
00062 return g;
00063 }
00064
00069 inline int32_t get_array_size()
00070 {
00071 return num_elements;
00072 }
00073
00078 inline int32_t get_num_elements() const
00079 {
00080 return last_element_idx+1;
00081 }
00082
00089 inline T get_element(int32_t index) const
00090 {
00091 return array[index];
00092 }
00093
00100 inline bool set_element(T element, int32_t index)
00101 {
00102 if (index < 0)
00103 {
00104 return false;
00105 }
00106 else if (index <= last_element_idx)
00107 {
00108 array[index]=element;
00109 return true;
00110 }
00111 else if (index < num_elements)
00112 {
00113 array[index]=element;
00114 last_element_idx=index;
00115 return true;
00116 }
00117 else
00118 {
00119 if (resize_array(index))
00120 return set_element(element, index);
00121 else
00122 return false;
00123 }
00124 }
00125
00132 inline bool insert_element(T element, int32_t index)
00133 {
00134 if (append_element(get_element(last_element_idx)))
00135 {
00136 for (int32_t i=last_element_idx-1; i>index; i--)
00137 {
00138 array[i]=array[i-1];
00139 }
00140 array[index]=element;
00141
00142 return true;
00143 }
00144
00145 return false;
00146 }
00147
00153 inline bool append_element(T element)
00154 {
00155 return set_element(element, last_element_idx+1);
00156 }
00157
00164 inline bool delete_element(int32_t idx)
00165 {
00166 if (idx>=0 && idx<=last_element_idx)
00167 {
00168 for (int32_t i=idx; i<last_element_idx; i++)
00169 array[i]=array[i+1];
00170
00171 array[last_element_idx]=0;
00172 last_element_idx--;
00173
00174 if ( num_elements - last_element_idx >= resize_granularity)
00175 resize_array(last_element_idx);
00176
00177 return true;
00178 }
00179
00180 return false;
00181 }
00182
00188 bool resize_array(int32_t n)
00189 {
00190 int32_t new_num_elements= ((n/resize_granularity)+1)*resize_granularity;
00191
00192 T* p= (T*) realloc(array, sizeof(T)*new_num_elements);
00193 if (p)
00194 {
00195 array=p;
00196 if (new_num_elements > num_elements)
00197 memset(&array[num_elements], 0, (new_num_elements-num_elements)*sizeof(T));
00198 else if (n+1<new_num_elements)
00199 memset(&array[n+1], 0, (new_num_elements-n-1)*sizeof(T));
00200
00201
00202 if (n-1<last_element_idx)
00203 last_element_idx=n-1;
00204
00205 num_elements=new_num_elements;
00206 return true;
00207 }
00208 else
00209 return false;
00210 }
00211
00219 inline T* get_array()
00220 {
00221 return array;
00222 }
00223
00230 inline void set_array(T* p_array, int32_t p_num_elements, int32_t array_size)
00231 {
00232 free(this->array);
00233 this->array=p_array;
00234 this->num_elements=array_size;
00235 this->last_element_idx=p_num_elements-1;
00236 }
00237
00239 inline void clear_array()
00240 {
00241 if (last_element_idx >= 0)
00242 memset(array, 0, (last_element_idx+1)*sizeof(T));
00243 }
00244
00254 inline T operator[](int32_t index) const
00255 {
00256 return array[index];
00257 }
00258
00264 CDynamicArray<T>& operator=(CDynamicArray<T>& orig)
00265 {
00266 resize_granularity=orig.resize_granularity;
00267 memcpy(array, orig.array, sizeof(T)*orig.num_elements);
00268 num_elements=orig.num_elements;
00269 last_element_idx=orig.last_element_idx;
00270
00271 return *this;
00272 }
00273
00274 protected:
00276 int32_t resize_granularity;
00277
00279 T* array;
00280
00282 int32_t num_elements;
00283
00285 int32_t last_element_idx;
00286 };
00287 #endif