Scippy

SoPlex

Sequential object-oriented simPlex

dataarray.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file dataarray.h
17  * @brief Save arrays of data objects.
18  */
19 #ifndef _DATAARRAY_H_
20 #define _DATAARRAY_H_
21 
22 #include <assert.h>
23 #include <stddef.h>
24 #include <string.h>
25 #include <iostream>
26 
27 #include "spxdefines.h"
28 #include "spxalloc.h"
29 
30 namespace soplex
31 {
32 /**@brief Safe arrays of data objects.
33  @ingroup Elementary
34 
35  Class DataArray provides safe arrays of \ref DataObjects. For general
36  C++ objects (in contrast to data objects) class Array is provided which
37  manages memory in a C++ compliant way.
38 
39  The elements of an instance of DataArray can be accessed just like
40  ordinary C++ array elements by means of the index operator[](). Safety is
41  provided by
42 
43  - automatic memory management in constructor and destructor
44  preventing memory leaks
45  - checking of array bounds when accessing elements with the
46  indexing operator[]() (only when compiled without \c -DNDEBUG).
47 
48  Moreover, #DataArray%s may easily be extended by #insert%ing or #append%ing
49  elements to the DataArray or shrunken by \ref remove() "removing" elements.
50  Method reSize(int n) resets the DataArray%s length to \p n thereby possibly
51  appending elements or truncating the DataArray to the required size.
52 
53  A DataArray may be used as arguments for standard C functions requiring
54  pointers through the use of get_ptr() and get_const_ptr().
55 
56  Internally, a DataArray object allocates a block of memory that fits up
57  to max() elements, only size() of them are used. This makes extension
58  and shrinking methods perform better.
59 
60  @see Array, \ref DataObjects "Data Objects"
61 */
62 template < class T >
63 class DataArray
64 {
65 private:
66  int thesize; ///< number of used elements in array data
67  int themax; ///< the length of array data and
68  T* data; ///< the array of elements
69 
70 protected:
71  /** When a DataArray is reSize()%d to more than max() elements, the
72  new value for max() is not just set to the new size but rather to
73  \p memFactor * \p size. This makes #reSize%ing perform better in codes
74  where a DataArray is extended often by a small number of elements
75  only.
76  */
77  Real memFactor; ///< memory extension factor.
78 
79 public:
80 
81  /// reference \p n 'th element.
82  T& operator[](int n)
83  {
84  assert(n >= 0);
85  assert(n < thesize);
86  return data[n];
87  }
88  /// reference \p n 'th const element.
89  const T& operator[](int n) const
90  {
91  assert(n >= 0);
92  assert(n < thesize);
93  return data[n];
94  }
95 
96  /// reference last element.
97  T& last()
98  {
99  assert(thesize > 0);
100  return data[thesize -1];
101  }
102  /// reference last const element.
103  const T& last() const
104  {
105  assert(thesize > 0);
106  return data[thesize -1];
107  }
108 
109  /// get a C pointer to the data.
110  T* get_ptr()
111  {
112  return data;
113  }
114  /// get a const C pointer to the data.
115  const T* get_const_ptr() const
116  {
117  return data;
118  }
119 
120  /// append element \p t.
121  void append(const T& t)
122  {
123  insert(thesize, 1, &t);
124  }
125  /// append \p n elements with value \p t.
126  void append(int n, const T& t)
127  {
128  insert(thesize, n, t);
129  }
130  /// append \p n elements from \p t.
131  void append(int n, const T t[])
132  {
133  insert(thesize, n, t);
134  }
135  /// append all elements from \p t.
136  void append(const DataArray<T>& t)
137  {
138  insert(thesize, t);
139  }
140 
141  /// insert \p n uninitialized elements before \p i 'th element.
142  void insert(int i, int n)
143  {
144  int j = thesize;
145 
146  assert(i >= 0);
147  assert(n >= 0);
148 
149  reSize(thesize + n);
150 
151  /// move \p n elements in memory from insert position \p i to the back
152  if( j > i )
153  memmove(&(data[i+n]), &(data[i]), (unsigned int) (j - i) * sizeof(T));
154  }
155 
156  /// insert \p n elements with value \p t before \p i 'the element.
157  void insert(int i, int n, const T& t)
158  {
159  if (n > 0)
160  {
161  insert(i, n);
162  for( int j = 0; j < n; j++ )
163  data[i + j] = t;
164  }
165  }
166 
167  /// insert \p n elements from \p t before \p i 'the element.
168  void insert(int i, int n, const T t[])
169  {
170  if (n > 0)
171  {
172  insert(i, n);
173  memcpy(&(data[i]), t, (unsigned int) n * sizeof(T));
174  }
175  }
176 
177  /// insert all elements from \p t before \p i 'th element.
178  void insert(int i, const DataArray<T>& t)
179  {
180  if (t.size())
181  {
182  insert(i, t.size());
183  memcpy(&(data[i]), t.data, (unsigned int)t.size() * sizeof(T));
184  }
185  }
186 
187  /// remove \p m elements starting at \p n.
188  void remove(int n = 0, int m = 1)
189  {
190  assert(n < size() && n >= 0);
191  /* use memmove instead of memcopy because the destination and the source might overlap */
192  if (n + m < size())
193  memmove(&(data[n]), &(data[n + m]), (unsigned int)(size() - (n + m)) * sizeof(T));
194  else
195  m = size() - n;
196  thesize -= m;
197  }
198  /// remove \p m last elements.
199  void removeLast(int m = 1)
200  {
201  assert(m <= size() && m >= 0);
202  thesize -= m;
203  }
204  /// remove all elements.
205  void clear()
206  {
207  thesize = 0;
208  }
209 
210  /// return nr. of elements.
211  int size() const
212  {
213  return thesize;
214  }
215 
216  /// reset size to \p newsize.
217  /** Resizing a DataArray to less than the previous size, involves
218  discarding its last elements. Resizing to a larger value involves
219  adding uninitialized elements (similar to append()). If neccessary,
220  also memory will be reallocated.
221  @param newsize the new number of elements the array can hold.
222  */
223  void reSize(int newsize)
224  {
225  assert(memFactor >= 1);
226  if (newsize > themax)
227  reMax(int(memFactor * newsize), newsize);
228  else if (newsize < 0)
229  thesize = 0;
230  else
231  thesize = newsize;
232  }
233 
234  /// return maximum number of elements.
235  /** Even though the DataArray currently holds no more than size()
236  elements, up to max() elements could be added without need to
237  reallocated free store.
238  */
239  int max() const
240  {
241  return themax;
242  }
243 
244  /// reset maximum number of elements.
245  /** The value of max() is reset to \p newMax thereby setting size()
246  to \p newSize. However, if \p newSize has a value \c < \c 0 (as the
247  default argument does) size() remains unchanged and max() is set
248  to MIN(size(), newMax). Hence, calling reMax() without the
249  default arguments, will reduce the memory consumption to a minimum.
250  In no instance max() will be set to a value less than 1 (even if
251  specified).
252 
253  */
254  void reMax(int newMax = 1, int newSize = -1)
255  {
256  if (newSize >= 0)
257  thesize = newSize;
258  if (newMax < newSize)
259  newMax = newSize;
260  if (newMax < 1)
261  newMax = 1;
262  if (newMax == themax)
263  return;
264  themax = newMax;
265  if (thesize <= 0)
266  {
267  /* no data needs to be copied so do a clean free and alloc */
268  spx_free(data);
269  spx_alloc(data, themax);
270  }
271  else
272  spx_realloc(data, themax);
273  }
274  /// assignment operator
276  {
277  if (this != &rhs)
278  {
279  reSize(rhs.size());
280  memcpy(data, rhs.data, (unsigned int) size() * sizeof(T));
281 
282  assert(isConsistent());
283  }
284  return *this;
285  }
286 
287  /// consistency check
288  bool isConsistent() const
289  {
290 #ifdef ENABLE_CONSISTENCY_CHECKS
291  if ( (data == 0)
292  || (themax < 1)
293  || (themax < thesize)
294  || (thesize < 0)
295  || (memFactor < 1.0))
296  return MSGinconsistent("DataArray");
297 #endif
298 
299  return true;
300  }
301 
302  /// copy constructor
303  DataArray(const DataArray& old)
304  : thesize(old.thesize)
305  , themax (old.themax)
306  , data (0)
307  , memFactor (old.memFactor)
308  {
309  spx_alloc(data, max());
310 
311  assert(thesize >= 0);
312 
313  if (thesize)
314  memcpy(data, old.data, (unsigned int)thesize * sizeof(T));
315 
316  assert(isConsistent());
317  }
318 
319  /// default constructor.
320  /** The constructor allocates an Array containing \p size uninitialized
321  elements. The internal array is allocated to have \p max nonzeros,
322  and the memory extension factor is set to \p fac.
323 
324  @param p_size number of unitialised elements.
325  @param p_max maximum number of elements the array can hold.
326  @param p_fac value for memFactor.
327  */
328  explicit DataArray(int p_size = 0, int p_max = 0, Real p_fac = 1.2)
329  : data (0)
330  , memFactor(p_fac)
331  {
332  thesize = (p_size < 0) ? 0 : p_size;
333  if (p_max > thesize)
334  themax = p_max;
335  else
336  themax = (thesize == 0) ? 1 : thesize;
337 
338  spx_alloc(data, themax);
339 
340  assert(isConsistent());
341  }
342 
343  /// destructor
345  {
346  if(data)
347  spx_free(data);
348  }
349 };
350 
351 } // namespace soplex
352 #endif // _DATAARRAY_H_
T & last()
reference last element.
Definition: dataarray.h:97
Safe arrays of data objects.Class DataArray provides safe arrays of Data Objects. For general C++ obj...
Definition: dataarray.h:63
Memory allocation routines.
DataArray & operator=(const DataArray &rhs)
assignment operator
Definition: dataarray.h:275
T * get_ptr()
get a C pointer to the data.
Definition: dataarray.h:110
void clear()
remove all elements.
Definition: dataarray.h:205
void insert(int i, int n, const T t[])
insert n elements from t before i &#39;the element.
Definition: dataarray.h:168
T * data
the array of elements
Definition: dataarray.h:68
void removeLast(int m=1)
remove m last elements.
Definition: dataarray.h:199
bool isConsistent() const
consistency check
Definition: dataarray.h:288
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:48
const T & operator[](int n) const
reference n &#39;th const element.
Definition: dataarray.h:89
double Real
SOPLEX_DEBUG.
Definition: spxdefines.h:200
~DataArray()
destructor
Definition: dataarray.h:344
int thesize
number of used elements in array data
Definition: dataarray.h:66
void insert(int i, const DataArray< T > &t)
insert all elements from t before i &#39;th element.
Definition: dataarray.h:178
const T * get_const_ptr() const
get a const C pointer to the data.
Definition: dataarray.h:115
void append(int n, const T t[])
append n elements from t.
Definition: dataarray.h:131
void append(const T &t)
append element t.
Definition: dataarray.h:121
int size() const
return nr. of elements.
Definition: dataarray.h:211
void append(const DataArray< T > &t)
append all elements from t.
Definition: dataarray.h:136
int themax
the length of array data and
Definition: dataarray.h:67
DataArray(const DataArray &old)
copy constructor
Definition: dataarray.h:303
void append(int n, const T &t)
append n elements with value t.
Definition: dataarray.h:126
Debugging, floating point type and parameter definitions.
void spx_realloc(T &p, int n)
Change amount of allocated memory.
Definition: spxalloc.h:79
Everything should be within this namespace.
const T & last() const
reference last const element.
Definition: dataarray.h:103
DataArray(int p_size=0, int p_max=0, Real p_fac=1.2)
default constructor.
Definition: dataarray.h:328
Real memFactor
memory extension factor.
Definition: dataarray.h:77
int max() const
return maximum number of elements.
Definition: dataarray.h:239
void insert(int i, int n, const T &t)
insert n elements with value t before i &#39;the element.
Definition: dataarray.h:157
#define MSGinconsistent(name)
Definition: spxdefines.h:121
void reMax(int newMax=1, int newSize=-1)
reset maximum number of elements.
Definition: dataarray.h:254
void insert(int i, int n)
insert n uninitialized elements before i &#39;th element.
Definition: dataarray.h:142
T & operator[](int n)
reference n &#39;th element.
Definition: dataarray.h:82
void reSize(int newsize)
reset size to newsize.
Definition: dataarray.h:223
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:109