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