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  nameset.h
26   	 * @brief Set of strings.
27   	 */
28   	#ifndef _NAMESET_H_
29   	#define _NAMESET_H_
30   	
31   	#include <assert.h>
32   	
33   	#include "soplex/spxdefines.h"
34   	#include "soplex/dataset.h"
35   	#include "soplex/datahashtable.h"
36   	#include "soplex/datakey.h"
37   	
38   	namespace soplex
39   	{
40   	/**@class NameSet
41   	   @brief   Set of strings.
42   	   @ingroup Elementary
43   	
44   	   Class NameSet implements a symbol or name table. It allows to store or
45   	   remove names (i.e., \c char*), but does not provide means for manipulating
46   	   stored names.
47   	
48   	   Names in a NameSet may be accessed via numbers from 0 through num()-1
49   	   and via \ref soplex::DataKey "DataKeys". See DataSet for a description of
50   	   these concepts.
51   	
52   	   At a time a NameSet can hold a maximum of max() entries. This can be
53   	   reset with method reMax(). If more than max() names are added to a
54   	   NameSet, it adjusts itself automatically to the required size.  This
55   	   implies, that references to names within a NameSet may become invalid if
56   	   the NameSet is expanded.
57   	
58   	   All names (i.e., the actual char strings) in a NameSet are stored in one
59   	   continuous memory block of size memMax(). At one time memSize() bytes of
60   	   it are used for actually saving names; the remaining memory is free to hold
61   	   additional names. memRemax() can be used to reset memMax() but not lower
62   	   than to memSize(). Method memPack() performs a garbage collection to
63   	   gain free memory resulting from removed names.
64   	
65   	   @warning Since the keys the NameSet uses to reference the strings are
66   	            generated internally, it is extremly important that the calls
67   	            to DataSet from within NameSet are synchronous to any calls
68   	            outside to DataSet, such as in row or column adding.
69   	*/
70   	class NameSet
71   	{
72   	public:
73   	
74   	   /**@brief   Handles of names in a NameSet.
75   	    * @ingroup Elementary
76   	    *
77   	    *  Class Name provides the handles (i.e., char*s) of names in a
78   	    *  NameSet.
79   	    */
(1) Event rule_of_three_violation: Class "soplex::NameSet::Name" has a user definition for at least one special function (copy constructor, copy assignment, destructor) but not all. If one of these functions requires a user definition then the others likely do as well.
(4) Event remediation: Add user-definition for a destructor.
Also see events: [copy_ctor][copy_assign]
80   	   class Name
81   	   {
82   	   private:
83   	
84   	      //------------------------------
85   	      /**@name Private Data */
86   	      ///@{
87   	      static const char deflt;     ///< default zero string.
88   	      ///@}
89   	
90   	   public:
91   	
92   	      //------------------------------
93   	      /**@name Public Data */
94   	      ///@{
95   	      const char* name;      ///< pointer to the name string.
96   	      ///@}
97   	
98   	      //------------------------------
99   	      /**@name Friends */
100  	      ///@{
101  	      /// equality operator.
102  	      friend int operator==(const Name& n1, const Name& n2)
103  	      {
104  	         return (strcmp(n1.name, n2.name) == 0);
105  	      }
106  	      /// output operator.
107  	      friend std::ostream& operator<<(std::ostream& out, const Name& n)
108  	      {
109  	         return out << n.name;
110  	      }
111  	      ///@}
112  	
113  	      //------------------------------
114  	      /**@name Debugging */
115  	      ///@{
116  	      /// consistency check.
117  	      bool isConsistent() const
118  	      {
119  	         return (name != 0);
120  	      }
121  	      ///@}
122  	
123  	      //------------------------------------
124  	      /**@name Constructors / destructors */
125  	      ///@{
126  	      /// default constructor.
127  	      Name()
128  	         : name(&deflt)
129  	      {}
130  	      /// copy constructor.
131  	      /** Only the pointer to the name is copied, but not the name itself.
132  	       */
(2) Event copy_ctor: User-defined copy constructor.
Also see events: [rule_of_three_violation][copy_assign][remediation]
133  	      Name(const Name& str)
134  	         : name(str.name)
135  	      {}
136  	      /// implictly constructs a Name out of a C style character string.
137  	      Name(const char* str)
138  	         : name(str)
139  	      {}
140  	
(3) Event copy_assign: User-defined copy assignment operator.
Also see events: [rule_of_three_violation][copy_ctor][remediation]
141  	      Name& operator=(const Name& old)
142  	      {
143  	         if(this != &old)
144  	            name = old.name;
145  	
146  	         return *this;
147  	      }
148  	      ///@}
149  	   };
150  	
151  	private:
152  	
153  	   //------------------------------
154  	   /**@name Data */
155  	   ///@{
156  	   DataSet < int > set;  ///< name set.
157  	   char* mem;            ///< string memory
158  	   int memmax;           ///< size of string memory
159  	   int memused;          ///< size of used string memory
160  	   /** Every name in a NameSet is assigned a DataKey by which it can be
161  	       accessed (see NameSet::operator[]()). See DataKey for a more
162  	       detailed description of the concept of Keys.
163  	   */
164  	   DataHashTable < Name, DataKey > hashtab;  ///< hashtable for names
165  	   ///@}
166  	
167  	public:
168  	
169  	   //------------------------------
170  	   /**@name Inquiry */
171  	   ///@{
172  	   /// returns \p num 'th name of NameSet.
173  	   const char* operator[](int pnum) const
174  	   {
175  	      return &mem[set[pnum]];
176  	   }
177  	
178  	   /// returns name for DataKey \p pkey of NameSet.
179  	   const char* operator[](const DataKey& pkey) const
180  	   {
181  	      return &mem[set[pkey]];
182  	   }
183  	
184  	   /// returns nr. of names in NameSet.
185  	   int num() const
186  	   {
187  	      return set.num();
188  	   }
189  	
190  	   /// returns maximum nr. of names that fit into NameSet.
191  	   int max() const
192  	   {
193  	      return set.max();
194  	   }
195  	
196  	   /// returns maximum DataKey::idx used in NameSet.
197  	   int size() const
198  	   {
199  	      return set.size();
200  	   }
201  	
202  	   /// returns maximum length of string memory.
203  	   int memMax() const
204  	   {
205  	      return memmax;
206  	   }
207  	
208  	   /// returns used length of string memory.
209  	   int memSize() const
210  	   {
211  	      return memused;
212  	   }
213  	
214  	   /// returns DataKey of the \p pnum 'th name in NameSet.
215  	   DataKey key(int pnum) const
216  	   {
217  	      return set.key(pnum);
218  	   }
219  	
220  	   /// returns DataKey of name \p str in NameSet.
221  	   DataKey key(const char* str) const
222  	   {
223  	      const Name nam(str);
224  	      const DataKey* result = hashtab.get(nam);
225  	      return result == 0 ? DataKey() : *hashtab.get(nam);
226  	   }
227  	
228  	   /// returns number of name with DataKey \p pkey in NameSet.
229  	   int number(const DataKey& pkey) const
230  	   {
231  	      return set.number(pkey);
232  	   }
233  	
234  	   /// returns number of name \p str in NameSet.
235  	   int number(const char* str) const
236  	   {
237  	      const Name nam(str);
238  	
239  	      if(hashtab.has(nam))
240  	      {
241  	         assert(hashtab.get(nam) != 0);
242  	         return number(*hashtab.get(nam));
243  	      }
244  	      else
245  	         return -1;
246  	   }
247  	
248  	   /// does NameSet has a name with number \p pnum?
249  	   bool has(int pnum) const
250  	   {
251  	      return set.has(pnum);
252  	   }
253  	
254  	   /// does NameSet has a name \p str?
255  	   bool has(const char* str) const
256  	   {
257  	      const Name nam(str);
258  	      return hashtab.has(nam);
259  	   }
260  	
261  	   /// does NameSet has a name with DataKey \p pkey?
262  	   bool has(const DataKey& pkey) const
263  	   {
264  	      return set.has(pkey);
265  	   }
266  	   ///@}
267  	
268  	   //----------------------------
269  	   /**@name Extension */
270  	   ///@{
271  	   ///
272  	   void add(const char* str);
273  	   /// adds name \p str to NameSet.
274  	   void add(DataKey& key, const char* str);
275  	
276  	   ///
277  	   void add(const NameSet& set);
278  	   /// adds all names in \p set to NameSet.
279  	   void add(DataKey key[], const NameSet& nset);
280  	   ///@}
281  	
282  	
283  	   //----------------------------
284  	   /**@name Shrinking */
285  	   ///@{
286  	   /// removes name with DataKey \p key from NameSet.
287  	   void remove(const DataKey& key);
288  	
289  	   /// removes \p pnum 'th name from NameSet.
290  	   void remove(int pnum)
291  	   {
292  	      remove(key(pnum));
293  	   }
294  	
295  	   /// removes name \p str from NameSet.
296  	   void remove(const char* str);
297  	
298  	   /// removes \p n names with DataKeys \p keys from NameSet.
299  	   void remove(const DataKey keys[], int n);
300  	
301  	   /// removes \p n names with numbers \p nums from NameSet.
302  	   void remove(const int nums[], int n);
303  	
304  	   /// remove all entries where \p dstat is less than zero.
305  	   void remove(int dstat[]);
306  	
307  	   /// removes all names from NameSet.
308  	   void clear();
309  	   ///@}
310  	
311  	
312  	   //----------------------------
313  	   /**@name Memory Control */
314  	   ///@{
315  	   /// resets max() to \p newmax.
316  	   void reMax(int newmax = 0);
317  	
318  	   /// resets memMax() to \p newmax.
319  	   void memRemax(int newmax = 0);
320  	
321  	   /// garbage collection.
322  	   void memPack();
323  	   ///@}
324  	
325  	
326  	   //----------------------------
327  	   /**@name Control Parameters */
328  	   ///@{
329  	   /// memory extension factor for entries.
330  	   /** When more than max() names are added to a NameSet, it is
331  	       automatically resized to fit the additional names. Parameter
332  	       \p factor is the factor by which the element memory is extended to do
333  	       so.
334  	    */
335  	   Real factor;
336  	
337  	   /// memory extension factor for names.
338  	   /** When the names added to a NameSet do no longer fit into the name
339  	       memory (i.e. the memory for saving the strings), it is automatically
340  	       resized to fit the additional names. Parameter \p memFactor is the
341  	       factor by which this memory is extended to do so.
342  	    */
343  	   Real memFactor;
344  	   ///@}
345  	
346  	   //----------------------------
347  	   /**@name Miscellaneous */
348  	   ///@{
349  	   /// consistency check.
350  	   bool isConsistent() const;
351  	   ///@}
352  	
353  	   //--------------------------------------
354  	   /**@name Constructors / Destructors */
355  	   ///@{
356  	   /// default constructor.
357  	   /** @param      max     start value for max()
358  	    *  @param      mmax    start value for memMax()
359  	    *  @param      fac     start value for #factor
360  	    *  @param      memFac  start value for #memFactor
361  	    */
362  	   explicit
363  	   NameSet(int max = 10000,
364  	           int mmax = -1,
365  	           Real fac = 2,
366  	           Real memFac = 2);
367  	
368  	   /// destructor.
369  	   ~NameSet();
370  	   ///@}
371  	
372  	private:
373  	
374  	   //--------------------------------------
375  	   /**@name Blocked */
376  	   ///@{
377  	   /// copy constructor.
378  	   NameSet(const NameSet& old);
379  	
380  	   /// assignment operator.
381  	   NameSet& operator=(const NameSet& rhs);
382  	   ///@}
383  	};
384  	
385  	extern std::ostream& operator<<(std::ostream& s, const NameSet& nset);
386  	
387  	} // namespace soplex
388  	#endif // _NAMESET_H_
389