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 
00030 template <class T> class CDynamicArray : public CSGObject
00031 {
00032     public:
00037         CDynamicArray(INT p_resize_granularity=128)
00038         : CSGObject()
00039         {
00040             this->resize_granularity=p_resize_granularity;
00041 
00042             array=(T*) calloc(p_resize_granularity, sizeof(T));
00043             ASSERT(array);
00044 
00045             num_elements=p_resize_granularity;
00046             last_element_idx=-1;
00047         }
00048 
00049         ~CDynamicArray() { free(array); }
00050 
00056         inline INT set_granularity(INT g)
00057         {
00058             g=CMath::max(g,128);
00059             this->resize_granularity = g;
00060             return g;
00061         }
00062 
00067         inline INT get_array_size()
00068         {
00069             return num_elements;
00070         }
00071 
00076         inline INT get_num_elements() const
00077         {
00078             return last_element_idx+1;
00079         }
00080 
00087         inline T get_element(INT index) const
00088         {
00089             return array[index];
00090         }
00091 
00098         inline bool set_element(T element, INT index)
00099         {
00100             if (index < 0)
00101             {
00102                 return false;
00103             }
00104             else if (index <= last_element_idx)
00105             {
00106                 array[index]=element;
00107                 return true;
00108             }
00109             else if (index < num_elements)
00110             {
00111                 array[index]=element;
00112                 last_element_idx=index;
00113                 return true;
00114             }
00115             else
00116             {
00117                 if (resize_array(index))
00118                     return set_element(element, index);
00119                 else
00120                     return false;
00121             }
00122         }
00123 
00130         inline bool insert_element(T element, INT index)
00131         {
00132             if (append_element(get_element(last_element_idx)))
00133             {
00134                 for (INT i=last_element_idx-1; i>index; i--)
00135                 {
00136                     array[i]=array[i-1];
00137                 }
00138                 array[index]=element;
00139 
00140                 return true;
00141             }
00142 
00143             return false;
00144         }
00145 
00151         inline bool append_element(T element)
00152         {
00153             return set_element(element, last_element_idx+1);
00154         }
00155 
00162         inline bool delete_element(INT idx)
00163         {
00164             if (idx>=0 && idx<=last_element_idx)
00165             {
00166                 for (INT i=idx; i<last_element_idx; i++)
00167                     array[i]=array[i+1];
00168 
00169                 array[last_element_idx]=0;
00170                 last_element_idx--;
00171 
00172                 if ( num_elements - last_element_idx >= resize_granularity)
00173                     resize_array(last_element_idx);
00174 
00175                 return true;
00176             }
00177 
00178             return false;
00179         }
00180 
00186         bool resize_array(INT n)
00187         {
00188             INT new_num_elements= ((n/resize_granularity)+1)*resize_granularity;
00189 
00190             T* p= (T*) realloc(array, sizeof(T)*new_num_elements);
00191             if (p)
00192             {
00193                 array=p;
00194                 if (new_num_elements > num_elements)
00195                     memset(&array[num_elements], 0, (new_num_elements-num_elements)*sizeof(T));
00196                 else if (n+1<new_num_elements)
00197                     memset(&array[n+1], 0, (new_num_elements-n-1)*sizeof(T));
00198 
00199                 //in case of shrinking we must adjust last element idx
00200                 if (n-1<last_element_idx)
00201                     last_element_idx=n-1;
00202 
00203                 num_elements=new_num_elements;
00204                 return true;
00205             }
00206             else
00207                 return false;
00208         }
00209 
00217         inline T* get_array()
00218         {
00219             return array;
00220         }
00221 
00228         inline void set_array(T* p_array, INT p_num_elements, INT array_size)
00229         {
00230             free(this->array);
00231             this->array=p_array;
00232             this->num_elements=array_size;
00233             this->last_element_idx=p_num_elements-1;
00234         }
00235 
00237         inline void clear_array()
00238         {
00239             if (last_element_idx >= 0)
00240                 memset(array, 0, (last_element_idx+1)*sizeof(T));
00241         }
00242 
00252         inline T operator[](INT index) const
00253         {
00254             return array[index];
00255         }
00256 
00262         CDynamicArray<T>& operator=(CDynamicArray<T>& orig)
00263         {
00264             resize_granularity=orig.resize_granularity;
00265             memcpy(array, orig.array, sizeof(T)*orig.num_elements);
00266             num_elements=orig.num_elements;
00267             last_element_idx=orig.last_element_idx;
00268 
00269             return *this;
00270         }
00271 
00272     protected:
00274         INT resize_granularity;
00275 
00277         T* array;
00278 
00280         INT num_elements;
00281 
00283         INT last_element_idx;
00284 };
00285 #endif

SHOGUN Machine Learning Toolbox - Documentation