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