DynamicArray.h

Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 1999-2008 Soeren Sonnenburg
00008  * Copyright (C) 1999-2008 Fraunhofer Institute FIRST and Max-Planck-Society
00009  */
00010 
00011 #ifndef _DYNARRAY_H_
00012 #define _DYNARRAY_H_
00013 
00014 /* workaround compile bug in R-modular interface */
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                 //in case of shrinking we must adjust last element idx
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

SHOGUN Machine Learning Toolbox - Documentation