Merge branch 'release-4-6'
[alexxy/gromacs.git] / src / gromacs / options / basicoptions.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2012,2013, 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  * Declares option objects for basic option types.
38  *
39  * Together with options.h, this header forms the part of the public API
40  * that most classes will use to provide options.
41  *
42  * \author Teemu Murtola <teemu.murtola@gmail.com>
43  * \inpublicapi
44  * \ingroup module_options
45  */
46 #ifndef GMX_OPTIONS_BASICOPTIONS_H
47 #define GMX_OPTIONS_BASICOPTIONS_H
48
49 #include <string>
50
51 #include "../utility/gmxassert.h"
52
53 #include "abstractoption.h"
54
55 namespace gmx
56 {
57
58 class BooleanOptionInfo;
59 class BooleanOptionStorage;
60 class IntegerOptionInfo;
61 class IntegerOptionStorage;
62 class DoubleOptionInfo;
63 class DoubleOptionStorage;
64 class StringOptionInfo;
65 class StringOptionStorage;
66
67 /*! \addtogroup module_options
68  * \{
69  */
70
71 /*! \brief
72  * Specifies an option that provides boolean values.
73  *
74  * Example:
75  * \code
76    bool  bPBC;
77    using gmx::BooleanOption;
78    options.addOption(BooleanOption("pbc").store(&bPBC));
79  * \endcode
80  *
81  * Public methods in this class do not throw.
82  *
83  * \inpublicapi
84  */
85 class BooleanOption : public OptionTemplate<bool, BooleanOption>
86 {
87     public:
88         //! OptionInfo subclass corresponding to this option type.
89         typedef BooleanOptionInfo InfoType;
90
91         //! Initializes an option with the given name.
92         explicit BooleanOption(const char *name) : MyBase(name) {}
93
94     private:
95         //! Creates a BooleanOptionStorage object.
96         virtual AbstractOptionStoragePointer createStorage() const;
97 };
98
99 /*! \brief
100  * Specifies an option that provides integer values.
101  *
102  * Examples:
103  * \code
104    using gmx::IntegerOption;
105    // Simple option
106    int  rcut = 0;
107    options.addOption(IntegerOption("rcut").store(&rcut));
108    // Vector-valued option
109    int  box[3] = {1, 1, 1};  // Default value
110    options.addOption(IntegerOption("box").store(box).vector());
111  * \endcode
112  *
113  * Public methods in this class do not throw.
114  *
115  * \inpublicapi
116  */
117 class IntegerOption : public OptionTemplate<int, IntegerOption>
118 {
119     public:
120         //! OptionInfo subclass corresponding to this option type.
121         typedef IntegerOptionInfo InfoType;
122
123         //! Initializes an option with the given name.
124         explicit IntegerOption(const char *name) : MyBase(name) {}
125
126         /*! \brief
127          * Sets the option to return a vector value.
128          *
129          * A vector value returns a fixed number of values, the default being
130          * three (can be changed with valueCount()).  However, it also accepts
131          * a single value, in which case the value is used to fill the whole
132          * vector.
133          */
134         MyClass &vector() { setVector(); return me(); }
135
136     private:
137         //! Creates an IntegerOptionStorage object.
138         virtual AbstractOptionStoragePointer createStorage() const;
139
140         /*! \brief
141          * Needed to initialize IntegerOptionStorage from this class without
142          * otherwise unnecessary accessors.
143          */
144         friend class IntegerOptionStorage;
145 };
146
147 /*! \brief
148  * Specifies an option that provides floating-point (double) values.
149  *
150  * Public methods in this class do not throw.
151  *
152  * \inpublicapi
153  */
154 class DoubleOption : public OptionTemplate<double, DoubleOption>
155 {
156     public:
157         //! OptionInfo subclass corresponding to this option type.
158         typedef DoubleOptionInfo InfoType;
159
160         //! Initializes an option with the given name.
161         explicit DoubleOption(const char *name) : MyBase(name), bTime_(false)
162         {
163         }
164
165         //! \copydoc IntegerOption::vector()
166         MyClass &vector() { setVector(); return me(); }
167         /*! \brief
168          * Marks this option as providing a time value whose unit can be changed.
169          *
170          * By itself, this option does nothing.  It marks the option as a time
171          * value such that TimeUnitManager::scaleTimeOptions() can process it.
172          * In typical cases, Gromacs scales the time options just before
173          * Options::finish() has been called, so the option value is only
174          * available after all option values have been processed.
175          * All values in the program are in ps (including any default value);
176          * user-provided values are scaled according to the time unit set in
177          * TimeUnitManager.
178          */
179         MyClass &timeValue() { bTime_ = true; return me(); }
180
181     private:
182         //! Creates a DoubleOptionStorage object.
183         virtual AbstractOptionStoragePointer createStorage() const;
184
185         bool bTime_;
186
187         /*! \brief
188          * Needed to initialize DoubleOptionStorage from this class without
189          * otherwise unnecessary accessors.
190          */
191         friend class DoubleOptionStorage;
192 };
193
194 /*! \brief
195  * Specifies an option that provides string values.
196  *
197  * Examples:
198  * \code
199    using gmx::StringOption;
200    // Simple option
201    std::string  str;
202    options.addOption(StringOption("str").store(&str));
203    // Option that only accepts predefined values
204    const char * const  allowed[] = { "atom", "residue", "molecule" };
205    std::string  str;
206    int          type;
207    options.addOption(StringOption("type").enumValue(allowed).store(&str)
208                         .storeEnumIndex(&type));
209  * \endcode
210  *
211  * Public methods in this class do not throw.
212  *
213  * \inpublicapi
214  */
215 class StringOption : public OptionTemplate<std::string, StringOption>
216 {
217     public:
218         //! OptionInfo subclass corresponding to this option type.
219         typedef StringOptionInfo InfoType;
220
221         //! Initializes an option with the given name.
222         explicit StringOption(const char *name)
223             : MyBase(name), enumValues_(NULL), enumValuesCount_(0),
224               defaultEnumIndex_(-1), enumIndexStore_(NULL)
225         {
226         }
227
228         /*! \brief
229          * Sets the option to only accept one of a fixed set of strings.
230          *
231          * \param[in] values  Array of strings to accept.
232          *
233          * Also accepts prefixes of the strings; if a prefix matches more than
234          * one of the possible strings, the shortest one is used (in a tie, the
235          * first one is).
236          *
237          * It is not possible to provide multiple values for an option with
238          * this property set, i.e., valueCount() and similar attributes cannot
239          * be set.
240          *
241          * The strings are copied once the option is created.
242          */
243         template <size_t count>
244         MyClass &enumValue(const char *const (&values)[count])
245         {
246             GMX_ASSERT(enumValues_ == NULL,
247                        "Multiple sets of enumerated values specified");
248             enumValues_      = values;
249             enumValuesCount_ = count;
250             return me();
251         }
252         /*! \brief
253          * Sets the option to only accept one of a fixed set of strings.
254          *
255          * \param[in] values  Array of strings to accept, with a NULL pointer
256          *      following the last string.
257          *
258          * Works otherwise as the array version, but accepts a pointer to
259          * an array of undetermined length.  The end of the array is indicated
260          * by a NULL pointer in the array.
261          *
262          * \see enumValue()
263          */
264         MyClass &enumValueFromNullTerminatedArray(const char *const *values)
265         {
266             GMX_ASSERT(enumValues_ == NULL,
267                        "Multiple sets of enumerated values specified");
268             enumValues_      = values;
269             enumValuesCount_ = -1;
270             return me();
271         }
272         /*! \brief
273          * Sets the default value using an index into the enumeration table.
274          *
275          * Cannot be specified without enumValue().
276          */
277         MyClass &defaultEnumIndex(int index)
278         {
279             GMX_ASSERT(index >= 0, "Invalid enumeration index");
280             defaultEnumIndex_ = index;
281             return me();
282         }
283         /*! \brief
284          * Stores the index of the selected value into the provided memory
285          * location.
286          *
287          * The index (zero-based) of the selected value in the array \p values
288          * provided to enumValues() is written into \p *store after the
289          * option gets its value.  If the option has not been provided,
290          * and there is no default value, -1 is stored.
291          *
292          * Cannot be specified without enumValue().
293          *
294          * \todo
295          * Implement this such that it is also possible to store the value
296          * directly into a real enum type.
297          */
298         MyClass &storeEnumIndex(int *store)
299         { enumIndexStore_ = store; return me(); }
300
301     private:
302         //! Creates a StringOptionStorage object.
303         virtual AbstractOptionStoragePointer createStorage() const;
304
305         const char *const      *enumValues_;
306         int                     enumValuesCount_;
307         int                     defaultEnumIndex_;
308         int                    *enumIndexStore_;
309
310         /*! \brief
311          * Needed to initialize StringOptionStorage from this class without
312          * otherwise unnecessary accessors.
313          */
314         friend class StringOptionStorage;
315 };
316
317 /*! \brief
318  * Wrapper class for accessing boolean option information.
319  *
320  * \inpublicapi
321  */
322 class BooleanOptionInfo : public OptionInfo
323 {
324     public:
325         //! Creates an option info object for the given option.
326         explicit BooleanOptionInfo(BooleanOptionStorage *option);
327 };
328
329 /*! \brief
330  * Wrapper class for accessing integer option information.
331  *
332  * \inpublicapi
333  */
334 class IntegerOptionInfo : public OptionInfo
335 {
336     public:
337         //! Creates an option info object for the given option.
338         explicit IntegerOptionInfo(IntegerOptionStorage *option);
339 };
340
341 /*! \brief
342  * Wrapper class for accessing floating-point option information.
343  *
344  * \inpublicapi
345  */
346 class DoubleOptionInfo : public OptionInfo
347 {
348     public:
349         //! Creates an option info object for the given option.
350         explicit DoubleOptionInfo(DoubleOptionStorage *option);
351
352         //! Whether the option specifies a time value.
353         bool isTime() const;
354
355         /*! \brief
356          * Sets a scale factor for user-provided values.
357          *
358          * Any user-provided value is scaled by the provided factor.
359          * Programmatically set default values are not scaled.
360          * If called multiple times, later calls override the previously set
361          * value.  In other words, the scaling is not cumulative.
362          */
363         void setScaleFactor(double factor);
364
365     private:
366         DoubleOptionStorage &option();
367         const DoubleOptionStorage &option() const;
368 };
369
370 /*! \brief
371  * Wrapper class for accessing string option information.
372  *
373  * \inpublicapi
374  */
375 class StringOptionInfo : public OptionInfo
376 {
377     public:
378         //! Creates an option info object for the given option.
379         explicit StringOptionInfo(StringOptionStorage *option);
380
381         /*! \brief
382          * Whether this option accepts an enumerated set of values.
383          *
384          * Returns true if StringOption::enumValues() was used when creating
385          * this option.
386          */
387         bool isEnumerated() const;
388         /*! \brief
389          * Returns the set of allowed values for this option.
390          *
391          * Returns an empty vector if isEnumerated() returns false.
392          */
393         const std::vector<std::string> &allowedValues() const;
394
395     private:
396         StringOptionStorage &option();
397         const StringOptionStorage &option() const;
398 };
399
400 /*!\}*/
401
402 } // namespace gmx
403
404 #endif