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  array.h
17   	 * @brief Save arrays of arbitrary types.
18   	 */
19   	#ifndef _ARRAY_H_
20   	#define _ARRAY_H_
21   	
22   	#include <assert.h>
23   	#include <string.h>
24   	#include <vector>
25   	#include "soplex/spxalloc.h"
26   	
27   	namespace soplex
28   	{
29   	/**@brief   Safe arrays of arbitrary types.
30   	   @ingroup Elementary
31   	
32   	   Class Array provides safe arrays of arbitrary type. Array elements are
33   	   accessed just like ordinary C++ array elements by means of the index
34   	   operator[](). Safety is provided by
35   	
36   	    - automatic memory management in constructor and destructor
37   	      preventing memory leaks
38   	    - checking of array bound when accessing elements with the
39   	      indexing operator[]() (only when compiled without \c -DNDEBUG).
40   	
41   	    Moreover, #Array%s may easily be extended by #insert%ing or
42   	    #append%ing elements to the Array or shrunken by
43   	    \ref remove() "removing"
44   	    elements. Method reSize(int n) resets the Array's length to \p n,
45   	    thereby appending elements or truncating the Array to the
46   	    required size.
47   	
48   	    An Array is implemented in a C++-compliant way with respect to
49   	    how memory is managed: Only operators new and delete are
50   	    used for allocating memory. This involves some overhead for all
51   	    methods effecting the length of an Array, i.e., all methods
52   	    insert(), append(), remove() and reSize(). This involves
53   	    allocating a new C++ array of the new size and copying all
54   	    elements with the template parameters operator=().
55   	
56   	    For this reason, it is not convenient to use class Array if its elements
57   	    are \ref DataObjects "Data Objects". In this case use class DataArray
58   	    instead.
59   	
60   	    @see DataArray, \ref DataObjects "Data Objects"
61   	*/
62   	template < class T >
63   	class Array
64   	{
65   	   static_assert(!std::is_same<T, bool>::value,
66   	                 "Since Array wraps std::vector, bool is not allowed to avoid unallowed behavior");
67   	protected:
68   	
69   	   //----------------------------------------
70   	   /**@name Data */
71   	   ///@{
72   	   std::vector<T> data;
73   	   ///@}
74   	
75   	public:
76   	
77   	   //----------------------------------------
78   	   /**@name Access / modification */
79   	   ///@{
80   	   /// reference \p n 'th element.
81   	   T& operator[](int n)
82   	   {
83   	      assert(n >= 0 && n < int(data.capacity()));
(1) Event neg_sink_parm_call: Passing "n" to "operator []", which cannot accept a negative number. [Note: The source code implementation of the function has been overridden by a builtin model.]
84   	      return data[n];
85   	   }
86   	   /// reference \p n 'th element.
87   	   const T& operator[](int n) const
88   	   {
89   	      assert(n >= 0 && n < int(data.capacity()));
90   	      return data[n];
91   	   }
92   	
93   	   /** This function serves for using a Vector in an C-style
94   	    *  function. It returns a pointer to the first value of the array.
95   	    */
96   	   T* get_ptr()
97   	   {
98   	      return data.data();
99   	   }
100  	   /// get a const C pointer to the data.
101  	   const T* get_const_ptr() const
102  	   {
103  	      return data.data();
104  	   }
105  	
106  	   /// append 1 elements with value \p t.
107  	   void append(const T& t)
108  	   {
109  	      data.push_back(t);
110  	   }
111  	   /// append \p n uninitialized elements.
112  	   void append(int n)
113  	   {
114  	      T newt = T();
115  	      this->append(n, newt);
116  	   }
117  	   /// append \p n elements with value \p t.
118  	   void append(int n, const T& t)
119  	   {
120  	      data.insert(data.end(), n, t);
121  	   }
122  	   /// append \p n elements from \p t.
123  	   void append(int n, const T t[])
124  	   {
125  	      data.insert(data.end(), t, t + n);
126  	   }
127  	   /// append all elements from \p p_array.
128  	   void append(const Array<T>& t)
129  	   {
130  	      data.insert(data.end(), t.data.begin(), t.data.end());
131  	   }
132  	
133  	   /// insert \p n uninitialized elements before \p i 'th element.
134  	   void insert(int i, int n)
135  	   {
136  	      T newt = T();
137  	
138  	      if(n > 0)
139  	         data.insert(data.begin() + i - 1, n, newt);
140  	   }
141  	
142  	   /// insert \p n elements with value \p t before \p i 'the element.
143  	   void insert(int i, int n, const T& t)
144  	   {
145  	      if(n > 0)
146  	      {
147  	         data.insert(data.begin() + i - 1, n, t);
148  	      }
149  	   }
150  	
151  	   /// insert \p n elements from \p p_array before \p i 'th element.
152  	   void insert(int i, int n, const T t[])
153  	   {
154  	      if(n > 0)
155  	      {
156  	         data.insert(data.begin() + i - 1, t, t + n);
157  	      }
158  	   }
159  	
160  	   /// insert all elements from \p p_array before \p i 'th element.
161  	   void insert(int i, const Array<T>& t)
162  	   {
163  	      if(t.size())
164  	      {
165  	         data.insert(data.begin() + i - 1, t.data.begin(), t.data.end());
166  	      }
167  	   }
168  	
169  	   /// remove \p m elements starting at \p n.
170  	   void remove(int n = 0, int m = 1)
171  	   {
172  	      assert(n < size() && n >= 0);
173  	
174  	      if(n + m < size())
175  	      {
176  	         data.erase(data.begin() + n, data.begin() + n + m);
177  	      }
178  	      else
179  	      {
180  	         data.erase(data.begin() + n, data.end());
181  	      }
182  	   }
183  	
184  	   /// remove all elements.
185  	   void clear()
186  	   {
187  	      data.clear();
188  	   }
189  	
190  	   /// return the number of elements.
191  	   int size() const
192  	   {
193  	      return int(data.size());
194  	   }
195  	
196  	   /// reset the number of elements.
197  	   void reSize(int newsize)
198  	   {
199  	      data.resize(newsize);
200  	   }
201  	
202  	   ///@}
203  	
204  	   //----------------------------------------
205  	   /**@name Construction / destruction */
206  	   ///@{
207  	   /// assignment operator.
208  	   Array<T>& operator=(const Array<T>& rhs)
209  	   {
210  	      if(this != &rhs)
211  	      {
212  	         reSize(rhs.size());
213  	         data = rhs.data;
214  	      }
215  	
216  	      return *this;
217  	   }
218  	
219  	   // Move assignment for Array
220  	   Array& operator=(const Array&& rhs)
221  	   {
222  	      data = std::move(rhs.data);
223  	      return *this;
224  	   }
225  	
226  	   /// default constructor.
227  	   /** The constructor allocates an Array of \p n uninitialized elements.
228  	    */
229  	   explicit
230  	   Array(int n = 0)
231  	   {
232  	      data.resize(n);
233  	   }
234  	
235  	   /// copy constructor
236  	   Array(const Array& old)
237  	   {
238  	      data = old.data;
239  	   }
240  	
241  	   /// destructor
242  	   ~Array()
243  	   {
244  	      ;
245  	   }
246  	
247  	   void push_back(const T& val)
248  	   {
249  	      data.push_back(val);
250  	   }
251  	
252  	   void push_back(T&& val)
253  	   {
254  	      data.push_back(val);
255  	   }
256  	
257  	   /// Consistency check.
258  	   bool isConsistent() const
259  	   {
260  	      return true;
261  	   }
262  	
263  	   ///@}
264  	};
265  	} // namespace soplex
266  	#endif // _ARRAY_H_
267