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 and a related template.
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/uniqueptr.h"
57
58 #include "optionflags.h"
59
60 namespace gmx
61 {
62
63 class AbstractOptionStorage;
64 template <typename T> class OptionStorageTemplate;
65 class Options;
66
67 //! Smart pointer for managing an AbstractOptionStorage object.
68 typedef gmx_unique_ptr<AbstractOptionStorage>::type
69         AbstractOptionStoragePointer;
70
71 /*! \brief
72  * Abstract base class for specifying option properties.
73  *
74  * Concrete classes should normally not derive directly from this class,
75  * but from OptionTemplate instead.  Classes derived from this class
76  * are mainly designed to implement the "named parameter" idiom.  For
77  * efficiency and clarity, these classes should only store values provided to
78  * them.  All error checking and memory management should be postponed to the
79  * point when the actual option is created.
80  *
81  * Subclasses should override createStorage() to create the correct type
82  * of storage object.
83  *
84  * \ingroup module_options
85  */
86 class AbstractOption
87 {
88     public:
89         // Virtual only for completeness, in normal use should not be needed.
90         virtual ~AbstractOption() { }
91
92     protected:
93         /*! \cond libapi */
94         //! Initializes the name and default values for an option.
95         explicit AbstractOption(const char *name)
96             : _minValueCount(1), _maxValueCount(1),
97               _name(name), _descr(NULL)
98         { }
99
100         /*! \brief
101          * Creates a default storage object for the option.
102          *
103          * \returns The created storage object.
104          * \throws  APIError if invalid option settings have been provided.
105          *
106          * This method is called by Options::addOption() when initializing an
107          * option from the settings.
108          *
109          * Derived classes should implement the method to create an actual
110          * storage object and populate it with correct values.
111          * They should also throw APIError if they detect problems.
112          *
113          * Should only be called by Options::addOption().
114          */
115         virtual AbstractOptionStoragePointer createStorage() const = 0;
116
117         /*! \brief
118          * Creates the description string for the option.
119          *
120          * \returns Description string for the option.
121          *
122          * This function is virtual to allow derived classes to customize the
123          * description programmatically, e.g., by adding the list of allowed
124          * values.
125          * The default implementation simply returns the user-provided
126          * description.
127          */
128         virtual std::string createDescription() const
129         { return _descr ? _descr : ""; }
130
131         //! Sets the description for the option.
132         void setDescription(const char *descr) { _descr = descr; }
133         //! Sets a flag for the option.
134         void setFlag(OptionFlag flag) { _flags.set(flag); }
135         //! Clears a flag for the option.
136         void clearFlag(OptionFlag flag) { _flags.clear(flag); }
137         //! Sets or clears a flag for the option.
138         void setFlag(OptionFlag flag, bool bSet) { _flags.set(flag, bSet); }
139         //! Returns true if the option is vector-valued.
140         bool isVector() const { return hasFlag(efVector); }
141         //! Sets the option to be vector-valued.
142         void setVector()
143         {
144             setFlag(efVector);
145             _minValueCount = 1;
146             if (_maxValueCount == 1)
147             {
148                 _maxValueCount = 3;
149             }
150         }
151         //! Sets the required number of values for the option.
152         void setValueCount(int count)
153         {
154             if (!hasFlag(efVector))
155             {
156                 _minValueCount = count;
157             }
158             _maxValueCount = count;
159         }
160
161         //! Minimum number of values required for the option.
162         int                     _minValueCount;
163         //! Maximum number of values allowed for the option.
164         int                     _maxValueCount;
165         //! \endcond
166
167     private:
168         //! Returns true if a flag has been set.
169         bool hasFlag(OptionFlag flag) const { return _flags.test(flag); }
170
171         const char             *_name;
172         //! Pointer to description of the option.
173         const char             *_descr;
174         OptionFlags             _flags;
175
176         /*! \brief
177          * Needed to initialize an AbstractOptionStorage object from this class
178          * without otherwise unnecessary accessors.
179          */
180         friend class AbstractOptionStorage;
181         /*! \brief
182          * Needed to be able to call createStorage().
183          */
184         friend class Options;
185 };
186
187 /*! \brief
188  * Templated base class for constructing concrete option settings classes.
189  *
190  * \tparam T Assignable type that stores a single option value.
191  * \tparam U Type of the derived class.
192  *
193  * This template is used as a base class like this:
194  * \code
195 class ConcreteOption : public OptionTemplate<int, ConcreteOption>
196 {
197  * \endcode
198  *
199  * All public functions in this class return \c *this casted to a reference to
200  * \p U.  They do not throw.
201  *
202  * For examples of how to use classes derived from this class, see the class
203  * documentation for Options.
204  *
205  * \inlibraryapi
206  * \ingroup module_options
207  */
208 template <typename T, class U>
209 class OptionTemplate : public AbstractOption
210 {
211     public:
212         //! Type that stores a single option value.
213         typedef T ValueType;
214         //! Alias for the derived class type.
215         typedef U MyClass;
216
217         /*! \brief
218          * Sets a description for the option.
219          *
220          * \param[in] descr Description to set.
221          *
222          * String in \p descr is copied when the option is created.
223          */
224         MyClass &description(const char *descr)
225         { setDescription(descr); return me(); }
226         //! Hides the option from normal help output.
227         MyClass &hidden(bool bHidden = true)
228         { setFlag(efHidden, bHidden); return me(); }
229         //! Requires the option to be specified explicitly.
230         MyClass &required(bool bRequired = true)
231         { setFlag(efRequired, bRequired); return me(); }
232         //! Allows the option to be specified multiple times.
233         MyClass &allowMultiple(bool bMulti = true)
234         { setFlag(efMulti, bMulti); return me(); }
235         //! Requires exactly \p count values for the option.
236         MyClass &valueCount(int count) { setValueCount(count); return me(); }
237         //! Allows any number of values for the option.
238         MyClass &multiValue() { _maxValueCount = -1; return me(); }
239
240         /*! \brief
241          * Sets a default value for the option.
242          *
243          * \param[in] defaultValue Default value.
244          *
245          * If the option is never set, the default value is copied to the
246          * assigned storage.  Note that if the option is not set and there
247          * is no default value, the storage is not altered, which can also be
248          * used to provide a default value.  The latter method has to be used
249          * if the option can take multiple values.
250          * If required() is specified, only affects the default value shown in
251          * help output.
252          *
253          * \p defaultValue is copied when the option is created.
254          */
255         MyClass &defaultValue(const T &defaultValue)
256         { _defaultValue = &defaultValue; return me(); }
257         /*! \brief
258          * Sets a default value for the option when it is set.
259          *
260          * \param[in] defaultValue Default value.
261          *
262          * This value is used if the option is set, but no value is provided.
263          * If the option is never set, the value set with defaultValue() is
264          * used.  Can only be used for options that accept a single value.
265          *
266          * \p defaultValue is copied when the option is created.
267          */
268         MyClass &defaultValueIfSet(const T &defaultValue)
269         { _defaultValueIfSet = &defaultValue; return me(); }
270         /*! \brief
271          * Stores value(s) in memory pointed by \p store.
272          *
273          * \param[in] store  Storage for option value(s).
274          *
275          * The caller is responsible for allocating enough memory such that
276          * the any allowed number of values fits into the array pointed by
277          * \p store.  If there is no maximum allowed number or if the maximum
278          * is inconveniently large, storeVector() should be used.
279          *
280          * For information on when values are available in the storage, see
281          * storeVector().
282          *
283          * The pointer provided should remain valid as long as the associated
284          * Options object exists.
285          */
286         MyClass &store(T *store)
287         { setFlag(efExternalStore); _store = store; return me(); }
288         /*! \brief
289          * Stores number of values in the value pointed by \p countptr.
290          *
291          * \param[in] countptr Storage for the number of values.
292          *
293          * For information on when values are available in the storage, see
294          * storeVector().
295          *
296          * The pointers provided should remain valid as long as the associated
297          * Options object exists.
298          */
299         MyClass &storeCount(int *countptr)
300         { _countptr = countptr; return me(); }
301         /*! \brief
302          * Stores option values in the provided vector.
303          *
304          * \param[in] store  Vector to store option values in.
305          *
306          * Values are added to the vector after each successful set of values
307          * is parsed.  Note that for some options, the value may be changed
308          * later, and is only guaranteed to be correct after Options::finish()
309          * has been called.
310          *
311          * The pointer provided should remain valid as long as the associated
312          * Options object exists.
313          */
314         MyClass &storeVector(std::vector<T> *store)
315         { setFlag(efExternalValueVector); _storeVector = store; return me(); }
316
317     protected:
318         /*! \cond libapi */
319         //! Alias for the template class for use in base classes.
320         typedef OptionTemplate<T, U> MyBase;
321
322         //! Initializes the name and default values for an option.
323         explicit OptionTemplate(const char *name)
324             : AbstractOption(name),
325               _defaultValue(NULL), _defaultValueIfSet(NULL), _store(NULL),
326               _countptr(NULL), _storeVector(NULL)
327         { }
328
329         /*! \brief
330          * Returns a pointer to user-specified default value, or NULL if there
331          * is none.
332          */
333         const T *defaultValue() const { return _defaultValue; }
334         /*! \brief
335          * Returns a pointer to user-specified default value, or NULL if there
336          * is none.
337          */
338         const T *defaultValueIfSet() const { return _defaultValueIfSet; }
339         //! Returns \p *this casted into MyClass to reduce typing.
340         MyClass &me() { return static_cast<MyClass &>(*this); }
341         //! \endcond
342
343     private:
344         const T                *_defaultValue;
345         const T                *_defaultValueIfSet;
346         T                      *_store;
347         int                    *_countptr;
348         std::vector<T>         *_storeVector;
349
350         /*! \brief
351          * Needed to initialize storage from this class without otherwise
352          * unnecessary accessors.
353          */
354         friend class OptionStorageTemplate<T>;
355 };
356
357 } // namespace gmx
358
359 #endif