00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef _ARRAY_H_
00012 #define _ARRAY_H_
00013
00014 #include <assert.h>
00015
00016
00017
00018
00019 #define ARRAY_ASSERT(x)
00020
00021 #include "lib/common.h"
00022 #include "base/SGObject.h"
00023
00024 #ifdef ARRAY_STATISTICS
00025 struct array_statistics {
00026 int32_t const_element;
00027 int32_t element;
00028 int32_t set_element;
00029 int32_t get_element;
00030 int32_t operator_overload;
00031 int32_t const_operator_overload;
00032 int32_t set_array;
00033 int32_t get_array;
00034 int32_t resize_array;
00035 int32_t array_element;
00036 };
00037
00038 #define DECLARE_ARRAY_STATISTICS struct array_statistics as
00039 #define INIT_ARRAY_STATISTICS memset(&as, 0, sizeof(as))
00040 #define PRINT_ARRAY_STATISTICS \
00041 SG_DEBUG("access statistics:\n" \
00042 "const element %i\n" \
00043 "element %i\n" \
00044 "set_element %i\n" \
00045 "get_element %i\n" \
00046 "operator_overload[] %i\n" \
00047 "const_operator_overload[] %i\n" \
00048 "set_array %i\n" \
00049 "get_array %i\n" \
00050 "resize_array %i\n" \
00051 "array_element %i\n", \
00052 as.const_element, \
00053 as.element, \
00054 as.set_element, \
00055 as.get_element, \
00056 as.operator_overload, \
00057 as.const_operator_overload, \
00058 as.set_array, \
00059 as.get_array, \
00060 as.resize_array, \
00061 as.array_element \
00062 );
00063
00064 #define INCREMENT_ARRAY_STATISTICS_VALUE(_val_) ((CArray<T>*)this)->as._val_++
00065
00066 #else
00067 #define DECLARE_ARRAY_STATISTICS
00068 #define INIT_ARRAY_STATISTICS
00069 #define PRINT_ARRAY_STATISTICS
00070 #define INCREMENT_ARRAY_STATISTICS_VALUE(_val_)
00071 #endif
00072
00079 template <class T> class CArray : public CSGObject
00080 {
00081 public:
00086 CArray(int32_t initial_size = 1)
00087 : CSGObject(), free_array(true), name(NULL)
00088 {
00089 INIT_ARRAY_STATISTICS;
00090 array_size = initial_size;
00091 array = (T*) calloc(array_size, sizeof(T));
00092 ARRAY_ASSERT(array);
00093 }
00094
00102 CArray(T* p_array, int32_t p_array_size, bool p_free_array=true,
00103 bool p_copy_array=false)
00104 : CSGObject(), array(NULL), free_array(false), name(NULL)
00105 {
00106 INIT_ARRAY_STATISTICS;
00107 set_array(p_array, p_array_size, p_free_array, p_copy_array);
00108 }
00109
00115 CArray(const T* p_array, int32_t p_array_size)
00116 : CSGObject(), array(NULL), free_array(false), name(NULL)
00117 {
00118 INIT_ARRAY_STATISTICS;
00119 set_array(p_array, p_array_size);
00120 }
00121
00122 ~CArray()
00123 {
00124 SG_DEBUG( "destroying CArray array '%s' of size %i\n",
00125 name? name : "unnamed", array_size);
00126 PRINT_ARRAY_STATISTICS;
00127 if (free_array)
00128 free(array);
00129 }
00130
00135 inline const char* get_name() const
00136 {
00137 return name;
00138 }
00139
00144 inline void set_name(const char * p_name)
00145 {
00146 name = p_name;
00147 }
00148
00153 inline int32_t get_array_size() const
00154 {
00155 return array_size;
00156 }
00157
00162 inline int32_t get_dim1()
00163 {
00164 return array_size;
00165 }
00166
00168 inline void zero()
00169 {
00170 for (int32_t i=0; i< array_size; i++)
00171 array[i]=0;
00172 }
00173
00179 inline const T& get_element(int32_t index) const
00180 {
00181 ARRAY_ASSERT(array && (index>=0) && (index<array_size));
00182 INCREMENT_ARRAY_STATISTICS_VALUE(get_element);
00183 return array[index];
00184 }
00185
00192 inline bool set_element(const T& p_element, int32_t index)
00193 {
00194 ARRAY_ASSERT(array && (index>=0) && (index<array_size));
00195 INCREMENT_ARRAY_STATISTICS_VALUE(set_element);
00196 array[index]=p_element;
00197 return true;
00198 }
00199
00205 inline const T& element(int32_t idx1) const
00206 {
00207 INCREMENT_ARRAY_STATISTICS_VALUE(const_element);
00208 return get_element(idx1);
00209 }
00210
00216 inline T& element(int32_t index)
00217 {
00218 ARRAY_ASSERT(array);
00219 ARRAY_ASSERT(index>=0);
00220 ARRAY_ASSERT(index<array_size);
00221 INCREMENT_ARRAY_STATISTICS_VALUE(element);
00222 return array[index];
00223 }
00224
00231 inline T& element(T* p_array, int32_t index)
00232 {
00233 ARRAY_ASSERT(array && (index>=0) && (index<array_size));
00234 ARRAY_ASSERT(array == p_array);
00235 INCREMENT_ARRAY_STATISTICS_VALUE(array_element);
00236 return p_array[index];
00237 }
00238
00244 bool resize_array(int32_t n)
00245 {
00246 INCREMENT_ARRAY_STATISTICS_VALUE(resize_array);
00247 ARRAY_ASSERT(free_array);
00248
00249 T* p= (T*) realloc(array, sizeof(T)*n);
00250 if (!p)
00251 return false;
00252 array=p;
00253 if (n > array_size)
00254 memset(&array[array_size], 0, (n-array_size)*sizeof(T));
00255 array_size=n;
00256 return true;
00257 }
00258
00265 inline T* get_array()
00266 {
00267 INCREMENT_ARRAY_STATISTICS_VALUE(get_array);
00268 return array;
00269 }
00270
00278 inline void set_array(T* p_array, int32_t p_array_size, bool p_free_array=true,
00279 bool copy_array=false)
00280 {
00281 INCREMENT_ARRAY_STATISTICS_VALUE(set_array);
00282 if (this->free_array)
00283 free(this->array);
00284 if (copy_array)
00285 {
00286 this->array=(T*)malloc(p_array_size*sizeof(T));
00287 memcpy(this->array, p_array, p_array_size*sizeof(T));
00288 }
00289 else
00290 this->array=p_array;
00291 this->array_size=p_array_size;
00292 this->free_array=p_free_array;
00293 }
00294
00300 inline void set_array(const T* p_array, int32_t p_array_size)
00301 {
00302 INCREMENT_ARRAY_STATISTICS_VALUE(set_array);
00303 free(this->array);
00304 this->array=(T*)malloc(p_array_size*sizeof(T));
00305 memcpy(this->array, p_array, p_array_size*sizeof(T));
00306 this->array_size=p_array_size;
00307 this->free_array=true;
00308 }
00309
00311 inline void clear_array()
00312 {
00313 memset(array, 0, array_size*sizeof(T));
00314 }
00315
00316
00325 inline const T& operator[](int32_t index) const
00326 {
00327 INCREMENT_ARRAY_STATISTICS_VALUE(const_operator_overload);
00328 return array[index];
00329 }
00330
00338 inline T& operator[](int32_t index)
00339 {
00340 INCREMENT_ARRAY_STATISTICS_VALUE(operator_overload);
00341 return element(index);
00342 }
00343
00349 CArray<T>& operator=(const CArray<T>& orig)
00350 {
00351 memcpy(array, orig.array, sizeof(T)*orig.array_size);
00352 array_size=orig.array_size;
00353
00354 return *this;
00355 }
00356
00358 void display_size() const
00359 {
00360 SG_PRINT( "Array '%s' of size: %d\n", name? name : "unnamed",
00361 array_size);
00362 }
00363
00365 void display_array() const
00366 {
00367 display_size();
00368 for (int32_t i=0; i<array_size; i++)
00369 SG_PRINT("%1.1f,", (float32_t)array[i]);
00370 SG_PRINT("\n");
00371 }
00372
00373 protected:
00375 T* array;
00377 int32_t array_size;
00379 bool free_array;
00381 const char *name;
00383 DECLARE_ARRAY_STATISTICS;
00384
00385 };
00386 #endif