source: branches/dev/Common/IpRegOptions.hpp @ 539

Last change on this file since 539 was 539, checked in by andreasw, 15 years ago

Corrected includes for ctype and stdio (the old OLD_C_HEADER was used).
(this bug was reported by Steven Dirkse)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.0 KB
Line 
1// Copyright (C) 2004, 2005 International Business Machines and others.
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// $Id: IpRegOptions.hpp 539 2005-10-12 17:42:11Z andreasw $
6//
7// Authors:  Carl Laird, Andreas Waechter     IBM    2005-06-18
8
9#ifndef __IPREGOPTIONS_HPP__
10#define __IPREGOPTIONS_HPP__
11
12#include "IpUtils.hpp"
13#include "IpReferenced.hpp"
14#include "IpException.hpp"
15#include "IpSmartPtr.hpp"
16#include <map>
17
18#ifdef HAVE_CSTDIO
19# include <cstdio>
20#else
21# ifdef HAVE_STDIO_H
22#  include <stdio.h>
23# else
24#  error "don't have header file for stdio"
25# endif
26#endif
27
28namespace Ipopt
29{
30
31  enum RegisteredOptionType
32  {
33    OT_Number,
34    OT_Integer,
35    OT_String,
36    OT_Unknown
37  };
38
39  /** Base class for registered options. The derived types are more
40   *  specific to a string option or a Number (real) option, etc.
41   */
42  class RegisteredOption : public ReferencedObject
43  {
44  public:
45    /** Constructors / Destructors */
46    //@{
47    RegisteredOption()
48        :
49        type_(OT_Unknown),
50        has_lower_(false),
51        has_upper_(false),
52        counter_(0)
53    {}
54
55    RegisteredOption(const std::string& name,
56                     const std::string& short_description,
57                     const std::string& long_description,
58                     const std::string& registering_category)
59        :
60        name_(name),
61        short_description_(short_description),
62        long_description_(long_description),
63        registering_category_(registering_category),
64        type_(OT_Unknown),
65        has_lower_(false),
66        has_upper_(false),
67        counter_(next_counter_++)
68    {}
69
70    RegisteredOption(const RegisteredOption& copy)
71        :
72        name_(copy.name_),
73        short_description_(copy.short_description_),
74        long_description_(copy.long_description_),
75        registering_category_(copy.registering_category_),
76        type_(copy.type_),
77        has_lower_(copy.has_lower_),
78        lower_(copy.lower_),
79        has_upper_(copy.has_upper_),
80        upper_(copy.upper_),
81        valid_strings_(copy.valid_strings_),
82        counter_(copy.counter_)
83    {}
84
85    virtual ~RegisteredOption()
86    {}
87    //@}
88
89    DECLARE_STD_EXCEPTION(ERROR_CONVERTING_STRING_TO_ENUM);
90
91    /** Standard Get / Set Methods */
92    //@{
93    /** Get the option's name (tag in the input file) */
94    const std::string& Name() const
95    {
96      return name_;
97    }
98    /** Set the option's name (tag in the input file) */
99    void SetName(const std::string& name)
100    {
101      name_ = name;
102    }
103    /** Get the short description */
104    const std::string& ShortDescription() const
105    {
106      return short_description_;
107    }
108    /** Get the long description */
109    const std::string& LongDescription() const
110    {
111      return long_description_;
112    }
113    /** Set the short description */
114    void SetShortDescription(const std::string& short_description)
115    {
116      short_description_ = short_description;
117    }
118    /** Set the long description */
119    void SetLongDescription(const std::string& long_description)
120    {
121      long_description_ = long_description;
122    }
123    /** Get the registering class */
124    const std::string& RegisteringCategory() const
125    {
126      return registering_category_;
127    }
128    /** Set the registering class */
129    void SetRegisteringCategory(const std::string& registering_category)
130    {
131      registering_category_ = registering_category;
132    }
133    /** Get the Option's type */
134    const RegisteredOptionType& Type() const
135    {
136      return type_;
137    }
138    /** Get the Option's type */
139    void SetType(const RegisteredOptionType& type)
140    {
141      type_ = type;
142    }
143    /** Counter */
144    Index Counter() const
145    {
146      return counter_;
147    }
148    //@}
149
150    /** @name Get / Set methods valid for specific types - NOTE: the Type
151     *  must be set before calling these methods.
152     */
153    //@{
154    /** check if the option has a lower bound - can be called for
155     *  OT_Number & OT_Integer*/
156    const bool& HasLower() const
157    {
158      DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer);
159      return has_lower_;
160    }
161    /** check if the lower bound is strict - can be called for
162    OT_Number */
163    const bool& LowerStrict() const
164    {
165      DBG_ASSERT(type_ == OT_Number && has_lower_ == true);
166      return lower_strict_;
167    }
168    /** get the Number version of the lower bound - can be called for
169     *  OT_Number */
170    Number LowerNumber() const
171    {
172      DBG_ASSERT(has_lower_ == true && type_ == OT_Number);
173      return lower_;
174    }
175    /** set the Number version of the lower bound - can be called for
176     *  OT_Number */
177    void SetLowerNumber(const Number& lower, const bool& strict)
178    {
179      DBG_ASSERT(type_ == OT_Number);
180      lower_ = lower;
181      lower_strict_ = strict, has_lower_ = true;
182    }
183    /** get the Integer version of the lower bound can be called for
184     *  OT_Integer*/
185    Index LowerInteger() const
186    {
187      DBG_ASSERT(has_lower_ == true && type_ == OT_Integer);
188      return (Index)lower_;
189    }
190    /** set the Integer version of the lower bound - can be called for
191     *  OT_Integer */
192    void SetLowerInteger(const Index& lower)
193    {
194      DBG_ASSERT(type_ == OT_Integer);
195      lower_ = (Number)lower;
196      has_lower_ = true;
197    }
198    /** check if the option has an upper bound - can be called for
199     *  OT_Number & OT_Integer*/
200    const bool& HasUpper() const
201    {
202      DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer);
203      return has_upper_;
204    }
205    /** check if the upper bound is strict - can be called for
206     *  OT_Number */
207    const bool& UpperStrict() const
208    {
209      DBG_ASSERT(type_ == OT_Number && has_upper_ == true);
210      return upper_strict_;
211    }
212    /** get the Number version of the upper bound - can be called for
213     *  OT_Number */
214    Number UpperNumber()
215    {
216      DBG_ASSERT(has_upper_ == true && type_ == OT_Number);
217      return upper_;
218    }
219    /** set the Number version of the upper bound - can be called for
220     *  OT_Number */
221    void SetUpperNumber(const Number& upper, const bool& strict)
222    {
223      DBG_ASSERT(type_ == OT_Number);
224      upper_ = upper;
225      upper_strict_ = strict;
226      has_upper_ = true;
227    }
228    /** get the Integer version of the upper bound - can be called for
229     *  OT_Integer*/
230    Index UpperInteger() const
231    {
232      DBG_ASSERT(has_upper_ == true && type_ == OT_Integer);
233      return (Index)upper_;
234    }
235    /** set the Integer version of the upper bound - can be called for
236     *  OT_Integer */
237    void SetUpperInteger(const Index& upper)
238    {
239      DBG_ASSERT(type_ == OT_Integer);
240      upper_ = (Number)upper;
241      has_upper_ = true;
242    }
243    /** method to add valid string entries - can be called for
244     *  OT_String */
245    void AddValidStringSetting(const std::string value,
246                               const std::string description)
247    {
248      DBG_ASSERT(type_ == OT_String);
249      valid_strings_.push_back(string_entry(value, description));
250    }
251    /** get the default as a Number - can be called for OT_Number */
252    Number DefaultNumber() const
253    {
254      DBG_ASSERT(type_ == OT_Number);
255      return default_number_;
256    }
257    /** Set the default as a Number - can be called for OT_Number */
258    void SetDefaultNumber(const Number& default_value)
259    {
260      DBG_ASSERT(type_ == OT_Number);
261      default_number_ = default_value;
262    }
263    /** get the default as an Integer - can be called for OT_Integer*/
264    Index DefaultInteger() const
265    {
266      DBG_ASSERT(type_ == OT_Integer);
267      return (Index)default_number_;
268    }
269    /** Set the default as an Integer - can be called for
270    OT_Integer */
271    void SetDefaultInteger(const Index& default_value)
272    {
273      DBG_ASSERT(type_ == OT_Integer);
274      default_number_ = (Number)default_value;
275    }
276    /** get the default as a string - can be called for OT_String */
277    std::string DefaultString() const
278    {
279      DBG_ASSERT(type_ == OT_String);
280      return default_string_;
281    }
282    /** get the default as a string, but as the index of the string in
283     *  the list - helps map from a string to an enum- can be called
284     *  for OT_String */
285    Index DefaultStringAsEnum() const
286    {
287      DBG_ASSERT(type_ == OT_String);
288      return MapStringSettingToEnum(default_string_);
289    }
290    /** Set the default as a string - can be called for OT_String */
291    void SetDefaultString(const std::string& default_value)
292    {
293      DBG_ASSERT(type_ == OT_String);
294      default_string_ = default_value;
295    }
296    /** Check if the Number value is a valid setting - can be called
297     *  for OT_Number */
298    bool IsValidNumberSetting(const Number& value) const
299    {
300      DBG_ASSERT(type_ == OT_Number);
301      if (has_lower_ && ((lower_strict_ == true && value <= lower_) ||
302                         (lower_strict_ == false && value < lower_))) {
303        return false;
304      }
305      if (has_upper_ && ((upper_strict_ == true && value >= upper_) ||
306                         (upper_strict_ == false && value > upper_))) {
307        return false;
308      }
309      return true;
310    }
311    /** Check if the Integer value is a valid setting - can be called
312     *  for OT_Integer */
313    bool IsValidIntegerSetting(const Index& value) const
314    {
315      DBG_ASSERT(type_ == OT_Integer);
316      if (has_lower_ && value < lower_) {
317        return false;
318      }
319      if (has_upper_ && value > upper_) {
320        return false;
321      }
322      return true;
323    }
324    /** Check if the String value is a valid setting - can be called
325     *  for OT_String */
326    bool IsValidStringSetting(const std::string& value) const;
327
328    /** Map a user setting (allowing any case) to the case used when
329     *  the setting was registered.
330     */
331    std::string MapStringSetting(const std::string& value) const;
332
333    /** Map a user setting (allowing any case) to the index of the
334     *  matched setting in the list of string settings. Helps map a
335     *  string setting to an enumeration.
336     */
337    Index MapStringSettingToEnum(const std::string& value) const;
338    //@}
339
340    /** output a description of the option */
341    void OutputDescription(const Journalist& jnlst) const;
342    /** output a more concise version */
343    void OutputShortDescription(const Journalist& jnlst) const;
344    /** output a latex version */
345    void OutputLatexDescription(const Journalist& jnlst) const;
346
347  private:
348    std::string name_;
349    std::string short_description_;
350    std::string long_description_;
351    std::string registering_category_;
352    RegisteredOptionType type_;
353
354    bool has_lower_;
355    bool lower_strict_;
356    Number lower_;
357    bool has_upper_;
358    bool upper_strict_;
359    Number upper_;
360    Number default_number_;
361
362    void MakeValidLatexString(std::string source, std::string& dest) const;
363    std::string MakeValidLatexNumber(Number value) const;
364
365    /** Compare two strings and return true if they are equal (case
366    insensitive comparison) */
367    bool string_equal_insensitive(const std::string& s1,
368                                  const std::string& s2) const;
369
370    /** class to hold the valid string settings for a string option */
371    class string_entry
372    {
373    public:
374      string_entry(const std::string& value, const std::string& description)
375          : value_(value), description_(description)
376      {}
377      std::string value_;
378      std::string description_;
379    };
380
381    std::vector<string_entry> valid_strings_;
382    std::string default_string_;
383
384    /** Has the information as how many-th option this one was
385     *  registered. */
386    const Index counter_;
387
388    static Index next_counter_;
389  };
390
391  /** Class for storing registered options. Used for validation and
392   *  documentation.
393   */
394  class RegisteredOptions : public ReferencedObject
395  {
396  public:
397    /** Constructors / Destructors */
398    //@{
399    /** Standard Constructor */
400    RegisteredOptions()
401        :
402        current_registering_category_("Uncategorized")
403    {}
404
405    /** Standard Destructor */
406    ~RegisteredOptions()
407    {}
408    //@}
409
410    DECLARE_STD_EXCEPTION(OPTION_ALREADY_REGISTERED);
411
412    /** Methods to interact with registered options */
413    //@{
414    /** set the registering class. All subsequent options will be
415     *  added with the registered class */
416    void SetRegisteringCategory(const std::string& registering_category)
417    {
418      current_registering_category_ = registering_category;
419    }
420
421    /** retrieve the value of the current registering category */
422    std::string RegisteringCategory()
423    {
424      return current_registering_category_;
425    }
426
427    /** Add a Number option (with no restrictions) */
428    void AddNumberOption(const std::string& name,
429                         const std::string& short_description,
430                         Number default_value,
431                         const std::string& long_description="");
432    /** Add a Number option (with a lower bound) */
433    void AddLowerBoundedNumberOption(const std::string& name,
434                                     const std::string& short_description,
435                                     Number lower, bool strict,
436                                     Number default_value,
437                                     const std::string& long_description="");
438    /** Add a Number option (with a upper bound) */
439    void AddUpperBoundedNumberOption(const std::string& name,
440                                     const std::string& short_description,
441                                     Number upper, bool strict,
442                                     Number default_value,
443                                     const std::string& long_description="");
444    /** Add a Number option (with a both bounds) */
445    void AddBoundedNumberOption(const std::string& name,
446                                const std::string& short_description,
447                                Number lower, bool lower_strict,
448                                Number upper, bool upper_strict,
449                                Number default_value,
450                                const std::string& long_description="");
451    /** Add a Integer option (with no restrictions) */
452    void AddIntegerOption(const std::string& name,
453                          const std::string& short_description,
454                          Index default_value,
455                          const std::string& long_description="");
456    /** Add a Integer option (with a lower bound) */
457    void AddLowerBoundedIntegerOption(const std::string& name,
458                                      const std::string& short_description,
459                                      Index lower, Index default_value,
460                                      const std::string& long_description="");
461    /** Add a Integer option (with a upper bound) */
462    void AddUpperBoundedIntegerOption(const std::string& name,
463                                      const std::string& short_description,
464                                      Index upper, Index default_value,
465                                      const std::string& long_description="");
466    /** Add a Integer option (with a both bounds) */
467    void AddBoundedIntegerOption(const std::string& name,
468                                 const std::string& short_description,
469                                 Index lower, Index upper,
470                                 Index default_value,
471                                 const std::string& long_description="");
472
473    /** Add a String option (with no restrictions) */
474    void AddStringOption(const std::string& name,
475                         const std::string& short_description,
476                         const std::string& default_value,
477                         const std::vector<std::string>& settings,
478                         const std::vector<std::string>& descriptions,
479                         const std::string& long_description="");
480    /** Methods that make adding string options with only a few
481     *  entries easier */
482    void AddStringOption1(const std::string& name,
483                          const std::string& short_description,
484                          const std::string& default_value,
485                          const std::string& setting1,
486                          const std::string& description1,
487                          const std::string& long_description="");
488    void AddStringOption2(const std::string& name,
489                          const std::string& short_description,
490                          const std::string& default_value,
491                          const std::string& setting1,
492                          const std::string& description1,
493                          const std::string& setting2,
494                          const std::string& description2,
495                          const std::string& long_description="");
496    void AddStringOption3(const std::string& name,
497                          const std::string& short_description,
498                          const std::string& default_value,
499                          const std::string& setting1,
500                          const std::string& description1,
501                          const std::string& setting2,
502                          const std::string& description2,
503                          const std::string& setting3,
504                          const std::string& description3,
505                          const std::string& long_description="");
506    void AddStringOption4(const std::string& name,
507                          const std::string& short_description,
508                          const std::string& default_value,
509                          const std::string& setting1,
510                          const std::string& description1,
511                          const std::string& setting2,
512                          const std::string& description2,
513                          const std::string& setting3,
514                          const std::string& description3,
515                          const std::string& setting4,
516                          const std::string& description4,
517                          const std::string& long_description="");
518    void AddStringOption5(const std::string& name,
519                          const std::string& short_description,
520                          const std::string& default_value,
521                          const std::string& setting1,
522                          const std::string& description1,
523                          const std::string& setting2,
524                          const std::string& description2,
525                          const std::string& setting3,
526                          const std::string& description3,
527                          const std::string& setting4,
528                          const std::string& description4,
529                          const std::string& setting5,
530                          const std::string& description5,
531                          const std::string& long_description="");
532    void AddStringOption6(const std::string& name,
533                          const std::string& short_description,
534                          const std::string& default_value,
535                          const std::string& setting1,
536                          const std::string& description1,
537                          const std::string& setting2,
538                          const std::string& description2,
539                          const std::string& setting3,
540                          const std::string& description3,
541                          const std::string& setting4,
542                          const std::string& description4,
543                          const std::string& setting5,
544                          const std::string& description5,
545                          const std::string& setting6,
546                          const std::string& description6,
547                          const std::string& long_description="");
548    void AddStringOption7(const std::string& name,
549                          const std::string& short_description,
550                          const std::string& default_value,
551                          const std::string& setting1,
552                          const std::string& description1,
553                          const std::string& setting2,
554                          const std::string& description2,
555                          const std::string& setting3,
556                          const std::string& description3,
557                          const std::string& setting4,
558                          const std::string& description4,
559                          const std::string& setting5,
560                          const std::string& description5,
561                          const std::string& setting6,
562                          const std::string& description6,
563                          const std::string& setting7,
564                          const std::string& description7,
565                          const std::string& long_description="");
566
567    /** Get a registered option - this will return NULL if the option
568     *  does not exist */
569    SmartPtr<const RegisteredOption> GetOption(const std::string& name);
570
571    /** Output documentation for the options - gives a description,
572     *  etc. */
573    void OutputOptionDocumentation(const Journalist& jnlst, std::list<std::string>& categories);
574
575    /** Output documentation in Latex format to include in a latex file */
576    void OutputLatexOptionDocumentation(const Journalist& jnlst, std::list<std::string>& categories);
577    //@}
578
579  private:
580    std::string current_registering_category_;
581    std::map<std::string, SmartPtr<RegisteredOption> > registered_options_;
582  };
583} // namespace Ipopt
584
585#endif
Note: See TracBrowser for help on using the repository browser.