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-2019 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 "soplex/spxdefines.h"
28 #include "soplex/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 
163  for(int j = 0; j < n; j++)
164  data[i + j] = t;
165  }
166  }
167 
168  /// insert \p n elements from \p t before \p i 'the element.
169  void insert(int i, int n, const T t[])
170  {
171  if(n > 0)
172  {
173  insert(i, n);
174  memcpy(&(data[i]), t, (unsigned int) n * sizeof(T));
175  }
176  }
177 
178  /// insert all elements from \p t before \p i 'th element.
179  void insert(int i, const DataArray<T>& t)
180  {
181  if(t.size())
182  {
183  insert(i, t.size());
184  memcpy(&(data[i]), t.data, (unsigned int)t.size() * sizeof(T));
185  }
186  }
187 
188  /// remove \p m elements starting at \p n.
189  void remove(int n = 0, int m = 1)
190  {
191  assert(n < size() && n >= 0);
192 
193  /* use memmove instead of memcopy because the destination and the source might overlap */
194  if(n + m < size())
195  memmove(&(data[n]), &(data[n + m]), (unsigned int)(size() - (n + m)) * sizeof(T));
196  else
197  m = size() - n;
198 
199  thesize -= m;
200  }
201  /// remove \p m last elements.
202  void removeLast(int m = 1)
203  {
204  assert(m <= size() && m >= 0);
205  thesize -= m;
206  }
207  /// remove all elements.
208  void clear()
209  {
210  thesize = 0;
211  }
212 
213  /// return nr. of elements.
214  int size() const
215  {
216  return thesize;
217  }
218 
219  /// reset size to \p newsize.
220  /** Resizing a DataArray to less than the previous size, involves
221  discarding its last elements. Resizing to a larger value involves
222  adding uninitialized elements (similar to append()). If neccessary,
223  also memory will be reallocated.
224  @param newsize the new number of elements the array can hold.
225  */
226  void reSize(int newsize)
227  {
228  assert(memFactor >= 1);
229 
230  if(newsize > themax)
231  reMax(int(memFactor * newsize), newsize);
232  else if(newsize < 0)
233  thesize = 0;
234  else
235  thesize = newsize;
236  }
237 
238  /// return maximum number of elements.
239  /** Even though the DataArray currently holds no more than size()
240  elements, up to max() elements could be added without need to
241  reallocated free store.
242  */
243  int max() const
244  {
245  return themax;
246  }
247 
248  /// reset maximum number of elements.
249  /** The value of max() is reset to \p newMax thereby setting size()
250  to \p newSize. However, if \p newSize has a value \c < \c 0 (as the
251  default argument does) size() remains unchanged and max() is set
252  to MIN(size(), newMax). Hence, calling reMax() without the
253  default arguments, will reduce the memory consumption to a minimum.
254  In no instance max() will be set to a value less than 1 (even if
255  specified).
256 
257  */
258  void reMax(int newMax = 1, int newSize = -1)
259  {
260  if(newSize >= 0)
261  thesize = newSize;
262 
263  if(newMax < newSize)
264  newMax = newSize;
265 
266  if(newMax < 1)
267  newMax = 1;
268 
269  if(newMax == themax)
270  return;
271 
272  themax = newMax;
273 
274  if(thesize <= 0)
275  {
276  /* no data needs to be copied so do a clean free and alloc */
277  spx_free(data);
278  spx_alloc(data, themax);
279  }
280  else
281  spx_realloc(data, themax);
282  }
283  /// assignment operator
285  {
286  if(this != &rhs)
287  {
288  reSize(rhs.size());
289  memcpy(data, rhs.data, (unsigned int) size() * sizeof(T));
290 
291  assert(isConsistent());
292  }
293 
294  return *this;
295  }
296 
297  /// consistency check
298  bool isConsistent() const
299  {
300 #ifdef ENABLE_CONSISTENCY_CHECKS
301 
302  if((data == 0)
303  || (themax < 1)
304  || (themax < thesize)
305  || (thesize < 0)
306  || (memFactor < 1.0))
307  return MSGinconsistent("DataArray");
308 
309 #endif
310 
311  return true;
312  }
313 
314  /// copy constructor
315  DataArray(const DataArray& old)
316  : thesize(old.thesize)
317  , themax(old.themax)
318  , data(0)
319  , memFactor(old.memFactor)
320  {
321  spx_alloc(data, max());
322 
323  assert(thesize >= 0);
324 
325  if(thesize)
326  memcpy(data, old.data, (unsigned int)thesize * sizeof(T));
327 
328  assert(isConsistent());
329  }
330 
331  /// default constructor.
332  /** The constructor allocates an Array containing \p size uninitialized
333  elements. The internal array is allocated to have \p max nonzeros,
334  and the memory extension factor is set to \p fac.
335 
336  @param p_size number of unitialised elements.
337  @param p_max maximum number of elements the array can hold.
338  @param p_fac value for memFactor.
339  */
340  explicit DataArray(int p_size = 0, int p_max = 0, Real p_fac = 1.2)
341  : data(0)
342  , memFactor(p_fac)
343  {
344  thesize = (p_size < 0) ? 0 : p_size;
345 
346  if(p_max > thesize)
347  themax = p_max;
348  else
349  themax = (thesize == 0) ? 1 : thesize;
350 
351  spx_alloc(data, themax);
352 
353  assert(isConsistent());
354  }
355 
356  /// destructor
358  {
359  if(data)
360  spx_free(data);
361  }
362 };
363 
364 } // namespace soplex
365 #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
bool isConsistent() const
consistency check
Definition: dataarray.h:298
Memory allocation routines.
DataArray & operator=(const DataArray &rhs)
assignment operator
Definition: dataarray.h:284
T * get_ptr()
get a C pointer to the data.
Definition: dataarray.h:110
void clear()
remove all elements.
Definition: dataarray.h:208
void insert(int i, int n, const T t[])
insert n elements from t before i &#39;the element.
Definition: dataarray.h:169
T * data
the array of elements
Definition: dataarray.h:68
void removeLast(int m=1)
remove m last elements.
Definition: dataarray.h:202
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:48
double Real
Definition: spxdefines.h:218
~DataArray()
destructor
Definition: dataarray.h:357
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:179
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 max() const
return maximum number of elements.
Definition: dataarray.h:243
const T * get_const_ptr() const
get a const C pointer to the data.
Definition: dataarray.h:115
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:315
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.
int size() const
return nr. of elements.
Definition: dataarray.h:214
DataArray(int p_size=0, int p_max=0, Real p_fac=1.2)
default constructor.
Definition: dataarray.h:340
Real memFactor
memory extension factor.
Definition: dataarray.h:77
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:126
void reMax(int newMax=1, int newSize=-1)
reset maximum number of elements.
Definition: dataarray.h:258
void insert(int i, int n)
insert n uninitialized elements before i &#39;th element.
Definition: dataarray.h:142
const T & operator[](int n) const
reference n &#39;th const element.
Definition: dataarray.h:89
T & operator[](int n)
reference n &#39;th element.
Definition: dataarray.h:82
void reSize(int newsize)
reset size to newsize.
Definition: dataarray.h:226
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:110
const T & last() const
reference last const element.
Definition: dataarray.h:103