SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DynArray.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 1999-2009 Soeren Sonnenburg
8  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  * Copyright (C) 2012 Engeniy Andreev (gsomix)
10  */
11 
12 #ifndef _DYNARRAY_H_
13 #define _DYNARRAY_H_
14 
15 #include <shogun/lib/common.h>
17 
18 namespace shogun
19 {
20 template <class T> class CDynamicArray;
21 
30 template <class T> class DynArray
31 {
32  template<class U> friend class CDynamicArray;
33  friend class CDynamicObjectArray;
34  friend class CCommUlongStringKernel;
35 
36  public:
42  DynArray(int32_t p_resize_granularity=128, bool tracable=true)
43  {
44  resize_granularity=p_resize_granularity;
45  free_array=true;
46  use_sg_mallocs=tracable;
47 
48  if (use_sg_mallocs)
49  array=SG_MALLOC(T, p_resize_granularity);
50  else
51  array=(T*) malloc(size_t(p_resize_granularity)*sizeof(T));
52 
53  num_elements=p_resize_granularity;
55  }
56 
65  DynArray(T* p_array, int32_t p_array_size, bool p_free_array, bool p_copy_array, bool tracable=true)
66  {
67  resize_granularity=p_array_size;
68  free_array=false;
69  use_sg_mallocs=tracable;
70 
71  array=NULL;
72  set_array(p_array, p_array_size, p_array_size, p_free_array, p_copy_array);
73  }
74 
81  DynArray(const T* p_array, int32_t p_array_size, bool tracable=true)
82  {
83  resize_granularity=p_array_size;
84  free_array=false;
85  use_sg_mallocs=tracable;
86 
87  array=NULL;
88  set_array(p_array, p_array_size, p_array_size);
89  }
90 
92  virtual ~DynArray()
93  {
94  if (array!=NULL && free_array)
95  {
96  if (use_sg_mallocs)
97  SG_FREE(array);
98  else
99  free(array);
100  }
101  }
102 
108  inline int32_t set_granularity(int32_t g)
109  {
110  g=CMath::max(g,128);
111  this->resize_granularity = g;
112  return g;
113  }
114 
119  inline int32_t get_array_size() const
120  {
121  return num_elements;
122  }
123 
128  inline int32_t get_num_elements() const
129  {
130  return current_num_elements;
131  }
132 
140  inline T get_element(int32_t index) const
141  {
142  return array[index];
143  }
144 
149  inline T get_last_element() const
150  {
151  return array[current_num_elements-1];
152  }
153 
161  inline T* get_element_ptr(int32_t index)
162  {
163  return &array[index];
164  }
165 
173  inline T get_element_safe(int32_t index) const
174  {
175  if (index>=get_num_elements())
176  {
177  SG_SERROR("array index out of bounds (%d >= %d)\n",
178  index, get_num_elements());
179  }
180  return array[index];
181  }
182 
189  inline bool set_element(T element, int32_t index)
190  {
191  if (index < 0)
192  {
193  return false;
194  }
195  else if (index <= current_num_elements-1)
196  {
197  array[index]=element;
198  return true;
199  }
200  else if (index < num_elements)
201  {
202  array[index]=element;
203  current_num_elements=index+1;
204  return true;
205  }
206  else
207  {
208  if (free_array && resize_array(index))
209  return set_element(element, index);
210  else
211  return false;
212  }
213  }
214 
221  inline bool insert_element(T element, int32_t index)
222  {
224  {
225  for (int32_t i=current_num_elements-2; i>index; i--)
226  {
227  array[i]=array[i-1];
228  }
229  array[index]=element;
230 
231  return true;
232  }
233 
234  return false;
235  }
236 
242  inline bool append_element(T element)
243  {
244  return set_element(element, current_num_elements);
245  }
246 
252  inline void push_back(T element)
253  {
254  if (get_num_elements() < 0)
255  set_element(element, 0);
256  else
257  set_element(element, get_num_elements());
258  }
259 
263  inline void pop_back()
264  {
265  if (get_num_elements() <= 0)
266  return;
267 
269  }
270 
276  inline T back() const
277  {
278  if (get_num_elements() <= 0)
279  return get_element(0);
280 
281  return get_element(get_num_elements()-1);
282  }
283 
290  int32_t find_element(T element) const
291  {
292  int32_t idx=-1;
293  int32_t num=get_num_elements();
294 
295  for (int32_t i=0; i<num; i++)
296  {
297  if (array[i] == element)
298  {
299  idx=i;
300  break;
301  }
302  }
303 
304  return idx;
305  }
306 
313  inline bool delete_element(int32_t idx)
314  {
315  if (idx>=0 && idx<=current_num_elements-1)
316  {
317  for (int32_t i=idx; i<current_num_elements-1; i++)
318  array[i]=array[i+1];
319 
320  current_num_elements--;
321 
322  if (num_elements - current_num_elements - 1
324  resize_array(current_num_elements);
325 
326  return true;
327  }
328 
329  return false;
330  }
331 
338  bool resize_array(int32_t n, bool exact_resize=false)
339  {
340  int32_t new_num_elements=n;
341 
342  if (!exact_resize)
343  {
344  new_num_elements=((n/resize_granularity)+1)*resize_granularity;
345  }
346 
347  T* p;
348 
349  if (use_sg_mallocs)
350  p = SG_REALLOC(T, array, num_elements, new_num_elements);
351  else
352  p = (T*) realloc(array, new_num_elements*sizeof(T));
353 
354  if (p || new_num_elements==0)
355  {
356  array=p;
357 
358  //in case of shrinking we must adjust last element idx
359  if (n-1<current_num_elements-1)
361 
362  num_elements=new_num_elements;
363  return true;
364  }
365  else
366  return false;
367  }
368 
376  inline T* get_array() const
377  {
378  return array;
379  }
380 
389  inline void set_array(T* p_array, int32_t p_num_elements,
390  int32_t p_array_size, bool p_free_array, bool p_copy_array)
391  {
392  if (array!=NULL && free_array)
393  SG_FREE(array);
394 
395  if (p_copy_array)
396  {
397  if (use_sg_mallocs)
398  array=SG_MALLOC(T, p_array_size);
399  else
400  array=(T*) malloc(p_array_size*sizeof(T));
401  memcpy(array, p_array, p_array_size*sizeof(T));
402  }
403  else
404  array=p_array;
405 
406  num_elements=p_array_size;
407  current_num_elements=p_num_elements;
408  free_array=p_free_array;
409  }
410 
417  inline void set_array(const T* p_array, int32_t p_num_elements,
418  int32_t p_array_size)
419  {
420  if (array!=NULL && free_array)
421  SG_FREE(array);
422 
423  if (use_sg_mallocs)
424  array=SG_MALLOC(T, p_array_size);
425  else
426  array=(T*) malloc(p_array_size*sizeof(T));
427  memcpy(array, p_array, p_array_size*sizeof(T));
428 
429  num_elements=p_array_size;
430  current_num_elements=p_num_elements;
431  free_array=true;
432  }
433 
435  inline void clear_array(T value)
436  {
437  if (current_num_elements-1 >= 0)
438  {
439  for (int32_t i=0; i<current_num_elements; i++)
440  array[i]=value;
441  }
442  }
443 
445  void reset(T value)
446  {
447  clear_array(value);
449  }
450 
452  void shuffle()
453  {
454  for (index_t i=0; i<=current_num_elements-1; ++i)
456  }
457 
459  void shuffle(CRandom * rand)
460  {
461  for (index_t i=0; i<=current_num_elements-1; ++i)
463  }
464 
466  void set_const(const T& const_element)
467  {
468  for (int32_t i=0; i<num_elements; i++)
469  array[i]=const_element;
470  }
471 
481  inline T operator[](int32_t index) const
482  {
483  return array[index];
484  }
485 
493  {
495 
496  /* check if orig array is larger than current, create new array */
497  if (orig.num_elements>num_elements)
498  {
499  SG_FREE(array);
500 
501  if (use_sg_mallocs)
502  array=SG_MALLOC(T, orig.num_elements);
503  else
504  array=(T*) malloc(sizeof(T)*orig.num_elements);
505  }
506 
507  memcpy(array, orig.array, sizeof(T)*orig.num_elements);
510 
511  return *this;
512  }
513 
515  virtual const char* get_name() const { return "DynArray"; }
516 
517  protected:
520 
522  T* array;
523 
525  int32_t num_elements;
526 
529 
532 
535 };
536 }
537 #endif /* _DYNARRAY_H_ */

SHOGUN Machine Learning Toolbox - Documentation