SHOGUN  3.2.1
 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/config.h>
16 
17 #include <shogun/lib/common.h>
19 
20 namespace shogun
21 {
22 template <class T> class CDynamicArray;
23 
32 template <class T> class DynArray
33 {
34  template<class U> friend class CDynamicArray;
35  friend class CDynamicObjectArray;
36  friend class CCommUlongStringKernel;
37 
38  public:
44  DynArray(int32_t p_resize_granularity=128, bool tracable=true)
45  {
46  resize_granularity=p_resize_granularity;
47  free_array=true;
48  use_sg_mallocs=tracable;
49 
50  if (use_sg_mallocs)
51  array=SG_MALLOC(T, p_resize_granularity);
52  else
53  array=(T*) malloc(size_t(p_resize_granularity)*sizeof(T));
54 
55  num_elements=p_resize_granularity;
57  }
58 
67  DynArray(T* p_array, int32_t p_array_size, bool p_free_array, bool p_copy_array, bool tracable=true)
68  {
69  resize_granularity=p_array_size;
70  free_array=false;
71  use_sg_mallocs=tracable;
72 
73  array=NULL;
74  set_array(p_array, p_array_size, p_array_size, p_free_array, p_copy_array);
75  }
76 
83  DynArray(const T* p_array, int32_t p_array_size, bool tracable=true)
84  {
85  resize_granularity=p_array_size;
86  free_array=false;
87  use_sg_mallocs=tracable;
88 
89  array=NULL;
90  set_array(p_array, p_array_size, p_array_size);
91  }
92 
94  virtual ~DynArray()
95  {
96  if (array!=NULL && free_array)
97  {
98  if (use_sg_mallocs)
99  SG_FREE(array);
100  else
101  free(array);
102  }
103  }
104 
110  inline int32_t set_granularity(int32_t g)
111  {
112  g=CMath::max(g,1);
113  this->resize_granularity = g;
114  return g;
115  }
116 
121  inline int32_t get_array_size() const
122  {
123  return num_elements;
124  }
125 
130  inline int32_t get_num_elements() const
131  {
132  return current_num_elements;
133  }
134 
142  inline T get_element(int32_t index) const
143  {
144  return array[index];
145  }
146 
151  inline T get_last_element() const
152  {
153  return array[current_num_elements-1];
154  }
155 
163  inline T* get_element_ptr(int32_t index)
164  {
165  return &array[index];
166  }
167 
175  inline T get_element_safe(int32_t index) const
176  {
177  if (index>=get_num_elements())
178  {
179  SG_SERROR("array index out of bounds (%d >= %d)\n",
180  index, get_num_elements());
181  }
182  return array[index];
183  }
184 
191  inline bool set_element(T element, int32_t index)
192  {
193  if (index < 0)
194  {
195  return false;
196  }
197  else if (index <= current_num_elements-1)
198  {
199  array[index]=element;
200  return true;
201  }
202  else if (index < num_elements)
203  {
204  array[index]=element;
205  current_num_elements=index+1;
206  return true;
207  }
208  else
209  {
210  if (free_array && resize_array(index))
211  return set_element(element, index);
212  else
213  return false;
214  }
215  }
216 
223  inline bool insert_element(T element, int32_t index)
224  {
226  {
227  for (int32_t i=current_num_elements-2; i>index; i--)
228  {
229  array[i]=array[i-1];
230  }
231  array[index]=element;
232 
233  return true;
234  }
235 
236  return false;
237  }
238 
244  inline bool append_element(T element)
245  {
246  return set_element(element, current_num_elements);
247  }
248 
254  inline void push_back(T element)
255  {
256  if (get_num_elements() < 0)
257  set_element(element, 0);
258  else
259  set_element(element, get_num_elements());
260  }
261 
265  inline void pop_back()
266  {
267  if (get_num_elements() <= 0)
268  return;
269 
271  }
272 
278  inline T back() const
279  {
280  if (get_num_elements() <= 0)
281  return get_element(0);
282 
283  return get_element(get_num_elements()-1);
284  }
285 
292  int32_t find_element(T element) const
293  {
294  int32_t idx=-1;
295  int32_t num=get_num_elements();
296 
297  for (int32_t i=0; i<num; i++)
298  {
299  if (array[i] == element)
300  {
301  idx=i;
302  break;
303  }
304  }
305 
306  return idx;
307  }
308 
315  inline bool delete_element(int32_t idx)
316  {
317  if (idx>=0 && idx<=current_num_elements-1)
318  {
319  for (int32_t i=idx; i<current_num_elements-1; i++)
320  array[i]=array[i+1];
321 
322  current_num_elements--;
323 
324  if (num_elements - current_num_elements - 1
326  resize_array(current_num_elements);
327 
328  return true;
329  }
330 
331  return false;
332  }
333 
340  bool resize_array(int32_t n, bool exact_resize=false)
341  {
342  int32_t new_num_elements=n;
343 
344  if (!exact_resize)
345  {
346  new_num_elements=((n/resize_granularity)+1)*resize_granularity;
347  }
348 
349 
350  if (use_sg_mallocs)
351  array = SG_REALLOC(T, array, num_elements, new_num_elements);
352  else
353  array = (T*) realloc(array, new_num_elements*sizeof(T));
354 
355  //in case of shrinking we must adjust last element idx
356  if (n-1<current_num_elements-1)
358 
359  num_elements=new_num_elements;
360  return true;
361 
362  return array || new_num_elements==0;
363  }
364 
372  inline T* get_array() const
373  {
374  return array;
375  }
376 
385  inline void set_array(T* p_array, int32_t p_num_elements,
386  int32_t p_array_size, bool p_free_array, bool p_copy_array)
387  {
388  if (array!=NULL && free_array)
389  SG_FREE(array);
390 
391  if (p_copy_array)
392  {
393  if (use_sg_mallocs)
394  array=SG_MALLOC(T, p_array_size);
395  else
396  array=(T*) malloc(p_array_size*sizeof(T));
397  memcpy(array, p_array, p_array_size*sizeof(T));
398  }
399  else
400  array=p_array;
401 
402  num_elements=p_array_size;
403  current_num_elements=p_num_elements;
404  free_array=p_free_array;
405  }
406 
413  inline void set_array(const T* p_array, int32_t p_num_elements,
414  int32_t p_array_size)
415  {
416  if (array!=NULL && free_array)
417  SG_FREE(array);
418 
419  if (use_sg_mallocs)
420  array=SG_MALLOC(T, p_array_size);
421  else
422  array=(T*) malloc(p_array_size*sizeof(T));
423  memcpy(array, p_array, p_array_size*sizeof(T));
424 
425  num_elements=p_array_size;
426  current_num_elements=p_num_elements;
427  free_array=true;
428  }
429 
431  inline void clear_array(T value)
432  {
433  if (current_num_elements-1 >= 0)
434  {
435  for (int32_t i=0; i<current_num_elements; i++)
436  array[i]=value;
437  }
438  }
439 
441  void reset(T value)
442  {
443  clear_array(value);
445  }
446 
448  void shuffle()
449  {
450  for (index_t i=0; i<=current_num_elements-1; ++i)
452  }
453 
455  void shuffle(CRandom * rand)
456  {
457  for (index_t i=0; i<=current_num_elements-1; ++i)
459  }
460 
462  void set_const(const T& const_element)
463  {
464  for (int32_t i=0; i<num_elements; i++)
465  array[i]=const_element;
466  }
467 
477  inline T operator[](int32_t index) const
478  {
479  return array[index];
480  }
481 
489  {
491 
492  /* check if orig array is larger than current, create new array */
493  if (orig.num_elements>num_elements)
494  {
495  SG_FREE(array);
496 
497  if (use_sg_mallocs)
498  array=SG_MALLOC(T, orig.num_elements);
499  else
500  array=(T*) malloc(sizeof(T)*orig.num_elements);
501  }
502 
503  memcpy(array, orig.array, sizeof(T)*orig.num_elements);
506 
507  return *this;
508  }
509 
511  virtual const char* get_name() const { return "DynArray"; }
512 
513  protected:
516 
518  T* array;
519 
521  int32_t num_elements;
522 
525 
528 
531 };
532 }
533 #endif /* _DYNARRAY_H_ */

SHOGUN Machine Learning Toolbox - Documentation