More generic way to obtain OptionInfo for options.
[alexxy/gromacs.git] / src / gromacs / options / basicoptions.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  * Declares option settings objects for basic option types.
34  *
35  * Together with options.h, this header forms the part of the public API
36  * that most classes will use to provide options.
37  *
38  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
39  * \inpublicapi
40  * \ingroup module_options
41  */
42 #ifndef GMX_OPTIONS_BASICOPTIONS_H
43 #define GMX_OPTIONS_BASICOPTIONS_H
44
45 #include <string>
46
47 #include "../utility/gmxassert.h"
48
49 #include "abstractoption.h"
50 #include "basicoptioninfo.h"
51
52 namespace gmx
53 {
54
55 class IntegerOptionStorage;
56 class DoubleOptionStorage;
57 class StringOptionStorage;
58
59 /*! \addtogroup module_options
60  * \{
61  */
62
63 /*! \brief
64  * Specifies an option that provides boolean values.
65  *
66  * Example:
67  * \code
68 bool  bPBC;
69 using gmx::BooleanOption;
70 options.addOption(BooleanOption("pbc").store(&bPBC));
71  * \endcode
72  *
73  * Public methods in this class do not throw.
74  *
75  * \inpublicapi
76  */
77 class BooleanOption : public OptionTemplate<bool, BooleanOption>
78 {
79     public:
80         //! OptionInfo subclass corresponding to this option type.
81         typedef BooleanOptionInfo InfoType;
82
83         //! Initializes an option with the given name.
84         explicit BooleanOption(const char *name) : MyBase(name) {}
85
86     private:
87         //! Creates a BooleanOptionStorage object.
88         virtual AbstractOptionStoragePointer createStorage() const;
89 };
90
91 /*! \brief
92  * Specifies an option that provides integer values.
93  *
94  * Examples:
95  * \code
96 using gmx::IntegerOption;
97 // Simple option
98 int  rcut = 0;
99 options.addOption(IntegerOption("rcut").store(&rcut));
100 // Vector-valued option
101 int  box[3] = {1, 1, 1};  // Default value
102 options.addOption(IntegerOption("box").store(box).vector());
103  * \endcode
104  *
105  * Public methods in this class do not throw.
106  *
107  * \inpublicapi
108  */
109 class IntegerOption : public OptionTemplate<int, IntegerOption>
110 {
111     public:
112         //! OptionInfo subclass corresponding to this option type.
113         typedef IntegerOptionInfo InfoType;
114
115         //! Initializes an option with the given name.
116         explicit IntegerOption(const char *name) : MyBase(name) {}
117
118         /*! \brief
119          * Sets the option to return a vector value.
120          *
121          * A vector value returns a fixed number of values, the default being
122          * three (can be changed with valueCount()).  However, it also accepts
123          * a single value, in which case the value is used to fill the whole
124          * vector.
125          */
126         MyClass &vector() { setVector(); return me(); }
127
128     private:
129         //! Creates an IntegerOptionStorage object.
130         virtual AbstractOptionStoragePointer createStorage() const;
131
132         /*! \brief
133          * Needed to initialize IntegerOptionStorage from this class without
134          * otherwise unnecessary accessors.
135          */
136         friend class IntegerOptionStorage;
137 };
138
139 /*! \brief
140  * Specifies an option that provides floating-point (double) values.
141  *
142  * Public methods in this class do not throw.
143  *
144  * \inpublicapi
145  */
146 class DoubleOption : public OptionTemplate<double, DoubleOption>
147 {
148     public:
149         //! OptionInfo subclass corresponding to this option type.
150         typedef DoubleOptionInfo InfoType;
151
152         //! Initializes an option with the given name.
153         explicit DoubleOption(const char *name) : MyBase(name), bTime_(false)
154         {
155         }
156
157         //! \copydoc IntegerOption::vector()
158         MyClass &vector() { setVector(); return me(); }
159         /*! \brief
160          * Marks this option as providing a time value whose unit can be changed.
161          *
162          * By itself, this option does nothing.  It marks the option as a time
163          * value such that TimeUnitManager::scaleTimeOptions() can process it.
164          * In typical cases, Gromacs scales the time options just before
165          * Options::finish() has been called, so the option value is only
166          * available after all option values have been processed.
167          * All values in the program are in ps (including any default value);
168          * user-provided values are scaled according to the time unit set in
169          * TimeUnitManager.
170          */
171         MyClass &timeValue() { bTime_ = true; return me(); }
172
173     private:
174         //! Creates a DoubleOptionStorage object.
175         virtual AbstractOptionStoragePointer createStorage() const;
176
177         bool bTime_;
178
179         /*! \brief
180          * Needed to initialize DoubleOptionStorage from this class without
181          * otherwise unnecessary accessors.
182          */
183         friend class DoubleOptionStorage;
184 };
185
186 /*! \brief
187  * Specifies an option that provides string values.
188  *
189  * Examples:
190  * \code
191 using gmx::StringOption;
192 // Simple option
193 std::string  str;
194 options.addOption(StringOption("str").store(&str));
195 // Option that only accepts predefined values
196 const char * const  allowed[] = { "atom", "residue", "molecule", NULL };
197 std::string  str;
198 int          type;
199 options.addOption(StringOption("type").enumValue(allowed).store(&str)
200                      .storeEnumIndex(&type));
201  * \endcode
202  *
203  * Public methods in this class do not throw.
204  *
205  * \inpublicapi
206  */
207 class StringOption : public OptionTemplate<std::string, StringOption>
208 {
209     public:
210         //! OptionInfo subclass corresponding to this option type.
211         typedef StringOptionInfo InfoType;
212
213         //! Initializes an option with the given name.
214         explicit StringOption(const char *name)
215             : MyBase(name), enumValues_(NULL), defaultEnumIndex_(-1),
216               enumIndexStore_(NULL)
217         {
218         }
219
220         /*! \brief
221          * Sets the option to only accept one of a fixed set of strings.
222          *
223          * \param[in] values  Array of strings to accept, a NULL pointer
224          *      following the last string.
225          *
226          * Also accepts prefixes of the strings; if a prefix matches more than
227          * one of the possible strings, the shortest one is used (in a tie, the
228          * first one is).
229          *
230          * It is not possible to provide multiple values for an option with
231          * this property set, i.e., valueCount() and similar attributes cannot
232          * be set.
233          *
234          * The strings are copied once the option is created.
235          */
236         MyClass &enumValue(const char *const *values)
237         { enumValues_ = values; return me(); }
238         /*! \brief
239          * Sets the default value using an index into the enumeration table.
240          *
241          * Cannot be specified without enumValue().
242          */
243         MyClass &defaultEnumIndex(int index)
244         {
245             GMX_RELEASE_ASSERT(index >= 0, "Invalid enumeration index");
246             defaultEnumIndex_ = index;
247             return me();
248         }
249         /*! \brief
250          * Stores the index of the selected value into the provided memory
251          * location.
252          *
253          * The index (zero-based) of the selected value in the array \p values
254          * provided to enumValues() is written into \p *store after the
255          * option gets its value.  If the option has not been provided,
256          * and there is no default value, -1 is stored.
257          *
258          * Cannot be specified without enumValue().
259          */
260         MyClass &storeEnumIndex(int *store)
261         { enumIndexStore_ = store; return me(); }
262
263     private:
264         //! Creates a StringOptionStorage object.
265         virtual AbstractOptionStoragePointer createStorage() const;
266         virtual std::string createDescription() const;
267
268         const char *const      *enumValues_;
269         int                     defaultEnumIndex_;
270         int                    *enumIndexStore_;
271
272         /*! \brief
273          * Needed to initialize StringOptionStorage from this class without
274          * otherwise unnecessary accessors.
275          */
276         friend class StringOptionStorage;
277 };
278
279 /*!\}*/
280
281 } // namespace gmx
282
283 #endif