1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2021 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