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 INT const_element;
00027 INT element;
00028 INT set_element;
00029 INT get_element;
00030 INT operator_overload;
00031 INT const_operator_overload;
00032 INT set_array;
00033 INT get_array;
00034 INT resize_array;
00035 INT 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
00074 template <class T> class CArray : public CSGObject
00075 {
00076 public:
00081 CArray(INT initial_size = 1)
00082 : CSGObject(), free_array(true), name(NULL)
00083 {
00084 INIT_ARRAY_STATISTICS;
00085 array_size = initial_size;
00086 array = (T*) calloc(array_size, sizeof(T));
00087 ARRAY_ASSERT(array);
00088 }
00089
00097 CArray(T* p_array, INT p_array_size, bool p_free_array=true,
00098 bool p_copy_array=false)
00099 : CSGObject(), array(NULL), free_array(false), name(NULL)
00100 {
00101 INIT_ARRAY_STATISTICS;
00102 set_array(p_array, p_array_size, p_free_array, p_copy_array);
00103 }
00104
00110 CArray(const T* p_array, INT p_array_size)
00111 : CSGObject(), array(NULL), free_array(false), name(NULL)
00112 {
00113 INIT_ARRAY_STATISTICS;
00114 set_array(p_array, p_array_size);
00115 }
00116
00117 ~CArray()
00118 {
00119 SG_DEBUG( "destroying CArray array '%s' of size %i\n",
00120 name? name : "unnamed", array_size);
00121 PRINT_ARRAY_STATISTICS;
00122 if (free_array)
00123 free(array);
00124 }
00125
00130 inline const char* get_name() const
00131 {
00132 return name;
00133 }
00134
00139 inline void set_name(const char * p_name)
00140 {
00141 name = p_name;
00142 }
00143
00148 inline INT get_array_size() const
00149 {
00150 return array_size;
00151 }
00152
00157 inline INT get_dim1()
00158 {
00159 return array_size;
00160 }
00161
00163 inline void zero()
00164 {
00165 for (INT i=0; i< array_size; i++)
00166 array[i]=0;
00167 }
00168
00174 inline const T& get_element(INT index) const
00175 {
00176 ARRAY_ASSERT(array && (index>=0) && (index<array_size));
00177 INCREMENT_ARRAY_STATISTICS_VALUE(get_element);
00178 return array[index];
00179 }
00180
00187 inline bool set_element(const T& p_element, INT index)
00188 {
00189 ARRAY_ASSERT(array && (index>=0) && (index<array_size));
00190 INCREMENT_ARRAY_STATISTICS_VALUE(set_element);
00191 array[index]=p_element;
00192 return true;
00193 }
00194
00200 inline const T& element(INT idx1) const
00201 {
00202 INCREMENT_ARRAY_STATISTICS_VALUE(const_element);
00203 return get_element(idx1);
00204 }
00205
00211 inline T& element(INT index)
00212 {
00213 ARRAY_ASSERT(array);
00214 ARRAY_ASSERT(index>=0);
00215 ARRAY_ASSERT(index<array_size);
00216 INCREMENT_ARRAY_STATISTICS_VALUE(element);
00217 return array[index];
00218 }
00219
00226 inline T& element(T* p_array, INT index)
00227 {
00228 ARRAY_ASSERT(array && (index>=0) && (index<array_size));
00229 ARRAY_ASSERT(array == p_array);
00230 INCREMENT_ARRAY_STATISTICS_VALUE(array_element);
00231 return p_array[index];
00232 }
00233
00239 bool resize_array(INT n)
00240 {
00241 INCREMENT_ARRAY_STATISTICS_VALUE(resize_array);
00242 ARRAY_ASSERT(free_array);
00243
00244 T* p= (T*) realloc(array, sizeof(T)*n);
00245 if (!p)
00246 return false;
00247 array=p;
00248 if (n > array_size)
00249 memset(&array[array_size], 0, (n-array_size)*sizeof(T));
00250 array_size=n;
00251 return true;
00252 }
00253
00260 inline T* get_array()
00261 {
00262 INCREMENT_ARRAY_STATISTICS_VALUE(get_array);
00263 return array;
00264 }
00265
00273 inline void set_array(T* p_array, INT p_array_size, bool p_free_array=true,
00274 bool copy_array=false)
00275 {
00276 INCREMENT_ARRAY_STATISTICS_VALUE(set_array);
00277 if (this->free_array)
00278 free(this->array);
00279 if (copy_array)
00280 {
00281 this->array=(T*)malloc(p_array_size*sizeof(T));
00282 memcpy(this->array, p_array, p_array_size*sizeof(T));
00283 }
00284 else
00285 this->array=p_array;
00286 this->array_size=p_array_size;
00287 this->free_array=p_free_array;
00288 }
00289
00295 inline void set_array(const T* p_array, INT p_array_size)
00296 {
00297 INCREMENT_ARRAY_STATISTICS_VALUE(set_array);
00298 free(this->array);
00299 this->array=(T*)malloc(p_array_size*sizeof(T));
00300 memcpy(this->array, p_array, p_array_size*sizeof(T));
00301 this->array_size=p_array_size;
00302 this->free_array=true;
00303 }
00304
00306 inline void clear_array()
00307 {
00308 memset(array, 0, array_size*sizeof(T));
00309 }
00310
00311
00320 inline const T& operator[](INT index) const
00321 {
00322 INCREMENT_ARRAY_STATISTICS_VALUE(const_operator_overload);
00323 return array[index];
00324 }
00325
00333 inline T& operator[](INT index)
00334 {
00335 INCREMENT_ARRAY_STATISTICS_VALUE(operator_overload);
00336 return element(index);
00337 }
00338
00344 CArray<T>& operator=(const CArray<T>& orig)
00345 {
00346 memcpy(array, orig.array, sizeof(T)*orig.array_size);
00347 array_size=orig.array_size;
00348
00349 return *this;
00350 }
00351
00353 void display_size() const
00354 {
00355 SG_PRINT( "Array '%s' of size: %d\n", name? name : "unnamed",
00356 array_size);
00357 }
00358
00360 void display_array() const
00361 {
00362 display_size();
00363 for (INT i=0; i<array_size; i++)
00364 SG_PRINT("%1.1f,", (float)array[i]);
00365 SG_PRINT("\n");
00366 }
00367
00368 protected:
00370 T* array;
00372 INT array_size;
00374 bool free_array;
00376 const char *name;
00378 DECLARE_ARRAY_STATISTICS;
00379
00380 };
00381 #endif