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  idxset.h
17   	 * @brief Set of indices.
18   	 */
19   	#ifndef _IDXSET_H_
20   	#define _IDXSET_H_
21   	
22   	#include "soplex/spxdefines.h"
23   	#include "soplex/spxalloc.h"
24   	#include <assert.h>
25   	
26   	namespace soplex
27   	{
28   	/**@brief   Set of indices.
29   	   @ingroup Elementary
30   	
31   	   Class IdxSet provides a set of indices. At construction it must be given
32   	   an array of int where to store the indice and its length. The array will
33   	   from then on be managed by the IdxSet.
34   	
35   	   Indices are implicitely numbered from 0 thru size()-1. They can be
36   	   accessed (and altered) via method index() with the desired index number as
37   	   argument.  Range checking is performed in the debug version.
38   	
39   	   Indices may be added or removed from the set, by calling add() or
40   	   remove() methods, respectively. However, no IdxSet can hold more then
41   	   max() indices, i.e. the number given at the constructor.
42   	
43   	   When removing indices, the remaining ones are renumbered. However, all
44   	   indices before the first removed index keep their number unchanged.
45   	
46   	   The internal structure of an IdxSet consists of an array #idx storing the
47   	   indices, its length len, and the actually used number of indices #num.
48   	   The class IdxSet doesn't allocate memory for the #idx array. Instead, the
49   	   user has to provide an adequate buffer to the constructor.
50   	
51   	   An IdxSet cannot be extended to fit more than max() elements. If
52   	   necessary, the user must explicitely provide the IdxSet with a
53   	   suitable memory. Alternatively, one can use \ref DIdxSet "DIdxSets"
54   	   which provide the required memory managemant.
55   	*/
56   	class IdxSet
57   	{
58   	protected:
59   	
60   	   //---------------------------------------
61   	   /**@name Data */
62   	   ///@{
63   	   int  num;           ///< number of used indices
64   	   int  len;           ///< length of array \ref soplex::IdxSet::idx "idx"
65   	   int* idx;           ///< array of indices
66   	   bool freeArray;     ///< true iff \ref soplex::IdxSet::idx "idx" should be freed inside of this object
67   	   ///@}
68   	
69   	public:
70   	
71   	   //---------------------------------------
72   	   /**@name Construction / destruction */
73   	   ///@{
74   	   /// constructor.
75   	   /** The constructur receives the index memory \p imem to use for saving
76   	       its indices. This must be large enough to fit \p n indices. \p l can
77   	       be given to construct an #IdxSet initialized to the \p l first
78   	       indices in \p imem.
79   	    */
80   	   IdxSet(int n, int imem[], int l = 0)
81   	      : num(l), len(n), idx(imem), freeArray(false)
82   	   {
83   	      assert(isConsistent());
84   	   }
85   	
86   	   /// default constructor.
87   	   /** The default constructor creates an index set with an empty index
88   	       space. You cannot store any indices in an #IdxSet created with
89   	       the default constructor.
90   	   */
91   	   IdxSet()
(1) Event write_constant_to_parm: Assigning: "this->num" = "0".
(2) Event write_constant_to_parm: Assigning: "this->len" = "0".
(3) Event write_constant_to_parm: Assigning: "this->idx" = "NULL".
(4) Event write_constant_to_parm: Assigning: "this->freeArray" = "false".
92   	      : num(0), len(0), idx(0), freeArray(false)
93   	   {
94   	      assert(isConsistent());
95   	   }
96   	
97   	   /// destructor.
98   	   virtual ~IdxSet()
99   	   {
100  	      if(freeArray)
101  	         spx_free(idx);
102  	   }
103  	
104  	   /// assignment operator.
105  	   /** The assignment operator copies all nonzeros of the right handside
106  	       #IdxSet to the left one. This implies, that the latter must have
107  	       enough index memory.
108  	    */
109  	   IdxSet& operator=(const IdxSet& set);
110  	   /// copy constructor.
111  	   IdxSet(const IdxSet&);
112  	   ///@}
113  	
114  	   //---------------------------------------
115  	   /**@name Access */
116  	   ///@{
117  	   /// access \p n 'th index.
118  	   int index(int n) const
119  	   {
120  	      assert(n >= 0 && n < size() && idx != 0);
121  	      return idx[n];
122  	   }
123  	   /// returns the number of used indices.
124  	   int size() const
125  	   {
126  	      return num;
127  	   }
128  	   /// returns the maximal number of indices which can be stored in IdxSet.
129  	   int max() const
130  	   {
131  	      return len;
132  	   }
133  	
134  	   /// returns the maximal index.
135  	   int dim() const;
136  	
137  	   /// returns the position of index \p i.
138  	   /** Finds the position of the first index \p i in the #IdxSet. If no index \p i is
139  	       available in the #IdxSet, -1 is returned. Otherwise,
140  	       index(pos(\p i)) == \p i holds.
141  	    */
142  	   int pos(int i) const;
143  	   ///@}
144  	
145  	   //---------------------------------------
146  	   /**@name Modification */
147  	   ///@{
148  	   /// appends \p n uninitialized indices.
149  	   void add(int n)
150  	   {
151  	      assert(n >= 0 && n + size() <= max());
152  	      num += n;
153  	   }
154  	
155  	   /// appends all indices of \p set.
156  	   void add(const IdxSet& set)
157  	   {
158  	      add(set.size(), set.idx);
159  	   }
160  	
161  	   /// appends \p n indices in \p i.
162  	   void add(int n, const int i[]);
163  	
164  	   /// appends index \p i.
165  	   void addIdx(int i)
166  	   {
167  	      assert(size() < max());
(1) Event deref_parm: Directly dereferencing parameter "this->idx".
168  	      idx[num++] = i;
169  	   }
170  	   /// removes indices at position numbers \p n through \p m.
171  	   void remove(int n, int m);
172  	
173  	   /// removes \p n 'th index.
174  	   void remove(int n)
175  	   {
176  	      //      /**@todo Shouldn't this be an assert instead of an if (see add()) */
177  	      //      if (n < size() && n >= 0)
178  	      //         idx[n] = idx[--num];
179  	      assert(n >= 0 && n < size());
180  	      idx[n] = idx[--num];
181  	   }
182  	
183  	   /// removes all indices.
184  	   void clear()
185  	   {
186  	      num = 0;
187  	   }
188  	   ///@}
189  	
190  	   //---------------------------------------
191  	   /**@name Consistency check */
192  	   ///@{
193  	   /// consistency check.
194  	   bool isConsistent() const;
195  	   ///@}
196  	};
197  	
198  	} // namespace soplex
199  	#endif // _IDXSET_H_
200