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