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