Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / options / abstractoption.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \file
32  * \brief
33  * Defines gmx::AbstractOption, gmx::OptionTemplate and gmx::OptionInfo.
34  *
35  * This header defines base classes for option settings that are used with
36  * Options::addOption().  These classes implement the "named parameter"
37  * idiom for specifying option properties.
38  *
39  * These classes also take care of creating and setting up the actual option
40  * objects.
41  *
42  * This header is needed directly only when implementing new option types,
43  * but methods of OptionTemplate are visible even to the normal user through
44  * its subclasses.
45  *
46  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
47  * \inlibraryapi
48  * \ingroup module_options
49  */
50 #ifndef GMX_OPTIONS_ABSTRACTOPTION_H
51 #define GMX_OPTIONS_ABSTRACTOPTION_H
52
53 #include <string>
54 #include <vector>
55
56 #include "../utility/common.h"
57 #include "../utility/uniqueptr.h"
58
59 #include "optionflags.h"
60
61 namespace gmx
62 {
63
64 class AbstractOptionStorage;
65 template <typename T> class OptionStorageTemplate;
66 class Options;
67
68 //! Smart pointer for managing an AbstractOptionStorage object.
69 typedef gmx_unique_ptr<AbstractOptionStorage>::type
70     AbstractOptionStoragePointer;
71
72 /*! \brief
73  * Abstract base class for specifying option properties.
74  *
75  * Concrete classes should normally not derive directly from this class,
76  * but from OptionTemplate instead.  Classes derived from this class
77  * are mainly designed to implement the "named parameter" idiom.  For
78  * efficiency and clarity, these classes should only store values provided to
79  * them.  All error checking and memory management should be postponed to the
80  * point when the actual option is created.
81  *
82  * Subclasses should override createStorage() to create the correct type
83  * of storage object.  If they use their own info type derived from OptionInfo,
84  * they should also have a public typedef \c InfoType that specifies that
85  * info type.  This is required for Options::addOption() to return the correct
86  * info type.
87  *
88  * \ingroup module_options
89  */
90 class AbstractOption
91 {
92     public:
93         // Virtual only for completeness, in normal use should not be needed.
94         virtual ~AbstractOption() { }
95
96     protected:
97         /*! \cond libapi */
98         //! Initializes the name and default values for an option.
99         explicit AbstractOption(const char *name)
100             : minValueCount_(1), maxValueCount_(1),
101               name_(name), descr_(NULL)
102         { }
103
104         /*! \brief
105          * Creates a default storage object for the option.
106          *
107          * \returns The created storage object.
108          * \throws  APIError if invalid option settings have been provided.
109          *
110          * This method is called by Options::addOption() when initializing an
111          * option from the settings.
112          *
113          * Derived classes should implement the method to create an actual
114          * storage object and populate it with correct values.
115          * They should also throw APIError if they detect problems.
116          *
117          * Should only be called by Options::addOption().
118          */
119         virtual AbstractOptionStoragePointer createStorage() const = 0;
120
121         /*! \brief
122          * Creates the description string for the option.
123          *
124          * \returns Description string for the option.
125          *
126          * This function is virtual to allow derived classes to customize the
127          * description programmatically, e.g., by adding the list of allowed
128          * values.
129          * The default implementation simply returns the user-provided
130          * description.
131          */
132         virtual std::string createDescription() const
133         { return descr_ ? descr_ : ""; }
134
135         //! Sets the description for the option.
136         void setDescription(const char *descr) { descr_ = descr; }
137         //! Sets a flag for the option.
138         void setFlag(OptionFlag flag) { flags_.set(flag); }
139         //! Clears a flag for the option.
140         void clearFlag(OptionFlag flag) { flags_.clear(flag); }
141         //! Sets or clears a flag for the option.
142         void setFlag(OptionFlag flag, bool bSet) { flags_.set(flag, bSet); }
143         //! Returns true if the option is vector-valued.
144         bool isVector() const { return hasFlag(efOption_Vector); }
145         /*! \brief
146          * Sets the option to be vector-valued.
147          *
148          * This method is provided for convenience to make management of value
149          * counts easier.  In order to implement a vector-valued option, the
150          * class derived from AbstractOption should expose a method that calls
151          * this method, and the storage object derived from
152          * AbstractOptionStorage should check isVector().
153          * If only a single value is provided, the storage object should fill
154          * the whole vector with that value.
155          *
156          * The length of the vector (the value of maxValueCount_) must be
157          * fixed.  The default length is 3 elements.
158          */
159         void setVector()
160         {
161             setFlag(efOption_Vector);
162             minValueCount_ = 1;
163             if (maxValueCount_ == 1)
164             {
165                 maxValueCount_ = 3;
166             }
167         }
168         //! Sets the required number of values for the option.
169         void setValueCount(int count)
170         {
171             if (!hasFlag(efOption_Vector))
172             {
173                 minValueCount_ = count;
174             }
175             maxValueCount_ = count;
176         }
177
178         //! Minimum number of values required for the option.
179         int                     minValueCount_;
180         //! Maximum number of values allowed for the option.
181         int                     maxValueCount_;
182         //! \endcond
183
184     private:
185         //! Returns true if a flag has been set.
186         bool hasFlag(OptionFlag flag) const { return flags_.test(flag); }
187
188         const char             *name_;
189         //! Pointer to description of the option.
190         const char             *descr_;
191         OptionFlags             flags_;
192
193         /*! \brief
194          * Needed to initialize an AbstractOptionStorage object from this class
195          * without otherwise unnecessary accessors.
196          */
197         friend class AbstractOptionStorage;
198         /*! \brief
199          * Needed to be able to call createStorage().
200          */
201         friend class Options;
202 };
203
204 /*! \brief
205  * Templated base class for constructing concrete option settings classes.
206  *
207  * \tparam T Assignable type that stores a single option value.
208  * \tparam U Type of the derived class.
209  *
210  * This template is used as a base class like this:
211  * \code
212    class ConcreteOption : public OptionTemplate<int, ConcreteOption>
213    {
214  * \endcode
215  *
216  * All public functions in this class return \c *this casted to a reference to
217  * \p U.  They do not throw.
218  *
219  * For examples of how to use classes derived from this class, see the class
220  * documentation for Options.
221  *
222  * \inlibraryapi
223  * \ingroup module_options
224  */
225 template <typename T, class U>
226 class OptionTemplate : public AbstractOption
227 {
228     public:
229         //! Type that stores a single option value.
230         typedef T ValueType;
231         //! Alias for the derived class type.
232         typedef U MyClass;
233
234         /*! \brief
235          * Sets a description for the option.
236          *
237          * \param[in] descr Description to set.
238          *
239          * String in \p descr is copied when the option is created.
240          */
241         MyClass &description(const char *descr)
242         { setDescription(descr); return me(); }
243         //! Hides the option from normal help output.
244         MyClass &hidden(bool bHidden = true)
245         { setFlag(efOption_Hidden, bHidden); return me(); }
246         /*! \brief
247          * Requires the option to be specified explicitly.
248          *
249          * Note that if you specify defaultValue() together with required(),
250          * the user is not required to explicitly provide the option.
251          * In this case, required() only affects possible help output.
252          */
253         MyClass &required(bool bRequired = true)
254         { setFlag(efOption_Required, bRequired); return me(); }
255         //! Allows the option to be specified multiple times.
256         MyClass &allowMultiple(bool bMulti = true)
257         { setFlag(efOption_MultipleTimes, bMulti); return me(); }
258         //! Requires exactly \p count values for the option.
259         MyClass &valueCount(int count) { setValueCount(count); return me(); }
260         //! Allows any number of values for the option.
261         MyClass &multiValue() { maxValueCount_ = -1; return me(); }
262
263         /*! \brief
264          * Sets a default value for the option.
265          *
266          * \param[in] defaultValue Default value.
267          *
268          * If the option is never set, the default value is copied to the
269          * assigned storage.  Note that if the option is not set and there
270          * is no default value, the storage is not altered, which can also be
271          * used to provide a default value.  The latter method has to be used
272          * if the option can take multiple values.
273          *
274          * \p defaultValue is copied when the option is created.
275          */
276         MyClass &defaultValue(const T &defaultValue)
277         { defaultValue_ = &defaultValue; return me(); }
278         /*! \brief
279          * Sets a default value for the option when it is set.
280          *
281          * \param[in] defaultValue Default value.
282          *
283          * This value is used if the option is set, but no value is provided.
284          * If the option is never set, the value set with defaultValue() is
285          * used.  Can only be used for options that accept a single value.
286          *
287          * \p defaultValue is copied when the option is created.
288          */
289         MyClass &defaultValueIfSet(const T &defaultValue)
290         { defaultValueIfSet_ = &defaultValue; return me(); }
291         /*! \brief
292          * Stores value(s) in memory pointed by \p store.
293          *
294          * \param[in] store  Storage for option value(s).
295          *
296          * The caller is responsible for allocating enough memory such that
297          * the any allowed number of values fits into the array pointed by
298          * \p store.  If there is no maximum allowed number or if the maximum
299          * is inconveniently large, storeVector() should be used.
300          *
301          * For information on when values are available in the storage, see
302          * storeVector().
303          *
304          * The pointer provided should remain valid as long as the associated
305          * Options object exists.
306          */
307         MyClass &store(T *store)
308         { store_ = store; return me(); }
309         /*! \brief
310          * Stores number of values in the value pointed by \p countptr.
311          *
312          * \param[in] countptr Storage for the number of values.
313          *
314          * For information on when values are available in the storage, see
315          * storeVector().
316          *
317          * The pointers provided should remain valid as long as the associated
318          * Options object exists.
319          */
320         MyClass &storeCount(int *countptr)
321         { countptr_ = countptr; return me(); }
322         /*! \brief
323          * Stores option values in the provided vector.
324          *
325          * \param[in] store  Vector to store option values in.
326          *
327          * Values are added to the vector after each successful set of values
328          * is parsed.  Note that for some options, the value may be changed
329          * later, and is only guaranteed to be correct after Options::finish()
330          * has been called.
331          *
332          * The pointer provided should remain valid as long as the associated
333          * Options object exists.
334          */
335         MyClass &storeVector(std::vector<T> *store)
336         { storeVector_ = store; return me(); }
337
338     protected:
339         /*! \cond libapi */
340         //! Alias for the template class for use in base classes.
341         typedef OptionTemplate<T, U> MyBase;
342
343         //! Initializes the name and default values for an option.
344         explicit OptionTemplate(const char *name)
345             : AbstractOption(name),
346               defaultValue_(NULL), defaultValueIfSet_(NULL), store_(NULL),
347               countptr_(NULL), storeVector_(NULL)
348         { }
349
350         /*! \brief
351          * Returns a pointer to user-specified default value, or NULL if there
352          * is none.
353          */
354         const T *defaultValue() const { return defaultValue_; }
355         /*! \brief
356          * Returns a pointer to user-specified default value, or NULL if there
357          * is none.
358          */
359         const T *defaultValueIfSet() const { return defaultValueIfSet_; }
360         //! Returns \p *this casted into MyClass to reduce typing.
361         MyClass &me() { return static_cast<MyClass &>(*this); }
362         //! \endcond
363
364     private:
365         const T                *defaultValue_;
366         const T                *defaultValueIfSet_;
367         T                      *store_;
368         int                    *countptr_;
369         std::vector<T>         *storeVector_;
370
371         /*! \brief
372          * Needed to initialize storage from this class without otherwise
373          * unnecessary accessors.
374          */
375         friend class OptionStorageTemplate<T>;
376 };
377
378 /*! \brief
379  * Gives information and allows modifications to an option after creation.
380  *
381  * When an option is added with Options::addOption(), an object of a subclass
382  * of OptionInfo is returned.  This object can be later used to access
383  * information about the option.  Non-const methods also allow later changing
384  * (some of) the option settings provided at initialization time.
385  * The properties accessible/modifiable through this interface are implemented
386  * based on need, and may not be implemented for all cases.
387  *
388  * \if libapi
389  * This class is also used by OptionsVisitor and OptionsModifyingVisitor as
390  * the interface that allows querying/modifying each visited option.
391  * \endif
392  *
393  * This class isolates the details of the internal option implementation from
394  * callers.  Although this class is a simple reference to the underlying
395  * implementation, it is implemented as non-copyable to allow const/non-const
396  * status of a reference to this class to indicate whether modifications are
397  * allowed.  Otherwise, separate classes would be needed for access and
398  * modification, complicating the implementation.  In the implementation,
399  * there is always a single OptionInfo instance referring to one option.
400  * The underlying implementation object always owns this instance, and only
401  * references are passed to callers.
402  *
403  * \see Options::addOption()
404  * \if libapi
405  * \see OptionsVisitor
406  * \see OptionsModifyingVisitor
407  * \endif
408  *
409  * \inpublicapi
410  * \ingroup module_options
411  */
412 class OptionInfo
413 {
414     public:
415         virtual ~OptionInfo();
416
417         /*! \brief
418          * Test whether the option is of a particular type.
419          *
420          * \tparam InfoType  Option type to test for. Should be a class derived
421          *      from OptionInfo.
422          */
423         template <class InfoType>
424         bool isType() const
425         {
426             return toType<InfoType>() != NULL;
427         }
428         /*! \brief
429          * Convert the info object to a particular type if the type is correct.
430          *
431          * \tparam InfoType  Option type to convert to. Should be a class
432          *      derived from OptionInfo.
433          * \retval this converted to a pointer to \p InfoType, or NULL if the
434          *      conversion is not possible.
435          */
436         template <class InfoType>
437         InfoType *toType()
438         {
439             return dynamic_cast<InfoType *>(this);
440         }
441         //! \copydoc toType()
442         template <class InfoType>
443         const InfoType *toType() const
444         {
445             return dynamic_cast<const InfoType *>(this);
446         }
447
448         //! Returns true if the option has been set.
449         bool isSet() const;
450         //! Returns true if the option is a hidden option.
451         bool isHidden() const;
452         //! Returns true if the option is required.
453         bool isRequired() const;
454         //! Returns the name of the option.
455         const std::string &name() const;
456         //! Returns the description of the option.
457         const std::string &description() const;
458         //! Returns the type of the option as a string.
459         const char *type() const;
460         //! Returns the number of values given for the option.
461         int valueCount() const;
462         //! Returns the i'th value of the option as a string.
463         std::string formatValue(int i) const;
464         /*! \brief
465          * Returns the default value if set for the option as a string.
466          *
467          * \see OptionTemplate::defaultValueIfSet()
468          */
469         std::string formatDefaultValueIfSet() const;
470
471     protected:
472         /*! \cond libapi */
473         /*! \brief
474          * Wraps a given option object.
475          *
476          * Does not throw.
477          */
478         explicit OptionInfo(AbstractOptionStorage *option);
479
480         //! Returns the wrapped option storage object.
481         AbstractOptionStorage       &option() { return option_; }
482         //! Returns the wrapped option storage object.
483         const AbstractOptionStorage &option() const { return option_; }
484         //! \endcond
485
486     private:
487         //! The wrapped option.
488         AbstractOptionStorage  &option_;
489
490         GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo);
491 };
492
493 } // namespace gmx
494
495 #endif