1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the class library                   */
4    	/*       SoPlex --- the Sequential object-oriented simPlex.                  */
5    	/*                                                                           */
6    	/*  Copyright (c) 1996-2023 Zuse Institute Berlin (ZIB)                      */
7    	/*                                                                           */
8    	/*  Licensed under the Apache License, Version 2.0 (the "License");          */
9    	/*  you may not use this file except in compliance with the License.         */
10   	/*  You may obtain a copy of the License at                                  */
11   	/*                                                                           */
12   	/*      http://www.apache.org/licenses/LICENSE-2.0                           */
13   	/*                                                                           */
14   	/*  Unless required by applicable law or agreed to in writing, software      */
15   	/*  distributed under the License is distributed on an "AS IS" BASIS,        */
16   	/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17   	/*  See the License for the specific language governing permissions and      */
18   	/*  limitations under the License.                                           */
19   	/*                                                                           */
20   	/*  You should have received a copy of the Apache-2.0 license                */
21   	/*  along with SoPlex; see the file LICENSE. If not email to soplex@zib.de.  */
22   	/*                                                                           */
23   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24   	
25   	/**@file  array.h
26   	 * @brief Save arrays of arbitrary types.
27   	 */
28   	#ifndef _ARRAY_H_
29   	#define _ARRAY_H_
30   	
31   	#include <assert.h>
32   	#include <string.h>
33   	#include <vector>
34   	#include "soplex/spxalloc.h"
35   	
36   	namespace soplex
37   	{
38   	/**@brief   Safe arrays of arbitrary types.
39   	   @ingroup Elementary
40   	
41   	   Class Array provides safe arrays of arbitrary type. Array elements are
42   	   accessed just like ordinary C++ array elements by means of the index
43   	   operator[](). Safety is provided by
44   	
45   	    - automatic memory management in constructor and destructor
46   	      preventing memory leaks
47   	    - checking of array bound when accessing elements with the
48   	      indexing operator[]() (only when compiled without \c -DNDEBUG).
49   	
50   	    Moreover, #Array%s may easily be extended by #insert%ing or
51   	    #append%ing elements to the Array or shrunken by
52   	    \ref remove() "removing"
53   	    elements. Method reSize(int n) resets the Array's length to \p n,
54   	    thereby appending elements or truncating the Array to the
55   	    required size.
56   	
57   	    An Array is implemented in a C++-compliant way with respect to
58   	    how memory is managed: Only operators new and delete are
59   	    used for allocating memory. This involves some overhead for all
60   	    methods effecting the length of an Array, i.e., all methods
61   	    insert(), append(), remove() and reSize(). This involves
62   	    allocating a new C++ array of the new size and copying all
63   	    elements with the template parameters operator=().
64   	
65   	    For this reason, it is not convenient to use class Array if its elements
66   	    are \ref DataObjects "Data Objects". In this case use class DataArray
67   	    instead.
68   	
69   	    @see DataArray, \ref DataObjects "Data Objects"
70   	*/
71   	template < class T >
(1) Event rule_of_five_violation: Class "soplex::Array<soplex::SPxPricer<double>::IdxElement>" has a user definition for at least one special function (copy constructor, move constructor, copy assignment, move assignment, destructor) but not all. If one of these functions requires a user definition then the others likely do as well.
(5) Event remediation: Add user-definition for a move constructor.
Also see events: [copy_ctor][copy_assign][destructor][move_assign]
72   	class Array
73   	{
74   	   static_assert(!std::is_same<T, bool>::value,
75   	                 "Since Array wraps std::vector, bool is not allowed to avoid unallowed behavior");
76   	protected:
77   	
78   	   //----------------------------------------
79   	   /**@name Data */
80   	   ///@{
81   	   std::vector<T> data;
82   	   ///@}
83   	
84   	public:
85   	
86   	   //----------------------------------------
87   	   /**@name Access / modification */
88   	   ///@{
89   	   /// reference \p n 'th element.
90   	   T& operator[](int n)
91   	   {
92   	      assert(n >= 0 && n < int(data.capacity()));
93   	      return data[n];
94   	   }
95   	   /// reference \p n 'th element.
96   	   const T& operator[](int n) const
97   	   {
98   	      assert(n >= 0 && n < int(data.capacity()));
99   	      return data[n];
100  	   }
101  	
102  	   /** This function serves for using a Vector in an C-style
103  	    *  function. It returns a pointer to the first value of the array.
104  	    */
105  	   T* get_ptr()
106  	   {
107  	      return data.data();
108  	   }
109  	   /// get a const C pointer to the data.
110  	   const T* get_const_ptr() const
111  	   {
112  	      return data.data();
113  	   }
114  	
115  	   /// append 1 elements with value \p t.
116  	   void append(const T& t)
117  	   {
118  	      data.push_back(t);
119  	   }
120  	   /// append \p n uninitialized elements.
121  	   void append(int n)
122  	   {
123  	      T newt = T();
124  	      this->append(n, newt);
125  	   }
126  	   /// append \p n elements with value \p t.
127  	   void append(int n, const T& t)
128  	   {
129  	      data.insert(data.end(), n, t);
130  	   }
131  	   /// append \p n elements from \p t.
132  	   void append(int n, const T t[])
133  	   {
134  	      data.insert(data.end(), t, t + n);
135  	   }
136  	   /// append all elements from \p p_array.
137  	   void append(const Array<T>& t)
138  	   {
139  	      data.insert(data.end(), t.data.begin(), t.data.end());
140  	   }
141  	
142  	   /// insert \p n uninitialized elements before \p i 'th element.
143  	   void insert(int i, int n)
144  	   {
145  	      T newt = T();
146  	
147  	      if(n > 0)
148  	         data.insert(data.begin() + i - 1, n, newt);
149  	   }
150  	
151  	   /// insert \p n elements with value \p t before \p i 'the element.
152  	   void insert(int i, int n, const T& t)
153  	   {
154  	      if(n > 0)
155  	      {
156  	         data.insert(data.begin() + i - 1, n, t);
157  	      }
158  	   }
159  	
160  	   /// insert \p n elements from \p p_array before \p i 'th element.
161  	   void insert(int i, int n, const T t[])
162  	   {
163  	      if(n > 0)
164  	      {
165  	         data.insert(data.begin() + i - 1, t, t + n);
166  	      }
167  	   }
168  	
169  	   /// insert all elements from \p p_array before \p i 'th element.
170  	   void insert(int i, const Array<T>& t)
171  	   {
172  	      if(t.size())
173  	      {
174  	         data.insert(data.begin() + i - 1, t.data.begin(), t.data.end());
175  	      }
176  	   }
177  	
178  	   /// remove \p m elements starting at \p n.
179  	   void remove(int n = 0, int m = 1)
180  	   {
181  	      assert(n < size() && n >= 0);
182  	
183  	      if(n + m < size())
184  	      {
185  	         data.erase(data.begin() + n, data.begin() + n + m);
186  	      }
187  	      else
188  	      {
189  	         data.erase(data.begin() + n, data.end());
190  	      }
191  	   }
192  	
193  	   /// remove all elements.
194  	   void clear()
195  	   {
196  	      data.clear();
197  	   }
198  	
199  	   /// return the number of elements.
200  	   int size() const
201  	   {
202  	      return int(data.size());
203  	   }
204  	
205  	   /// reset the number of elements.
206  	   void reSize(int newsize)
207  	   {
208  	      data.resize(newsize);
209  	   }
210  	
211  	   ///@}
212  	
213  	   //----------------------------------------
214  	   /**@name Construction / destruction */
215  	   ///@{
216  	   /// assignment operator.
(3) Event copy_assign: User-defined copy assignment operator.
Also see events: [rule_of_five_violation][copy_ctor][destructor][remediation][move_assign]
217  	   Array<T>& operator=(const Array<T>& rhs)
218  	   {
219  	      if(this != &rhs)
220  	      {
221  	         reSize(rhs.size());
222  	         data = rhs.data;
223  	      }
224  	
225  	      return *this;
226  	   }
227  	
228  	   // Move assignment for Array
(6) Event move_assign: User-defined move assignment operator.
Also see events: [rule_of_five_violation][copy_ctor][copy_assign][destructor][remediation]
229  	   Array& operator=(const Array&& rhs)
230  	   {
231  	      data = std::move(rhs.data);
232  	      return *this;
233  	   }
234  	
235  	   /// default constructor.
236  	   /** The constructor allocates an Array of \p n uninitialized elements.
237  	    */
238  	   explicit
239  	   Array(int n = 0)
240  	   {
241  	      data.resize(n);
242  	   }
243  	
244  	   /// copy constructor
(2) Event copy_ctor: User-defined copy constructor.
Also see events: [rule_of_five_violation][copy_assign][destructor][remediation][move_assign]
245  	   Array(const Array& old)
246  	   {
247  	      data = old.data;
248  	   }
249  	
250  	   /// destructor
(4) Event destructor: User-defined destructor.
Also see events: [rule_of_five_violation][copy_ctor][copy_assign][remediation][move_assign]
251  	   ~Array()
252  	   {
253  	      ;
254  	   }
255  	
256  	   void push_back(const T& val)
257  	   {
258  	      data.push_back(val);
259  	   }
260  	
261  	   void push_back(T&& val)
262  	   {
263  	      data.push_back(val);
264  	   }
265  	
266  	   /// Consistency check.
267  	   bool isConsistent() const
268  	   {
269  	      return true;
270  	   }
271  	
272  	   ///@}
273  	};
274  	} // namespace soplex
275  	#endif // _ARRAY_H_
276