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,2014, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source 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 "../legacyheaders/types/simple.h"
52 #include "../utility/gmxassert.h"
53
54 #include "abstractoption.h"
55
56 namespace gmx
57 {
58
59 class BooleanOptionInfo;
60 class BooleanOptionStorage;
61 class IntegerOptionInfo;
62 class IntegerOptionStorage;
63 class Int64OptionInfo;
64 class Int64OptionStorage;
65 class DoubleOptionInfo;
66 class DoubleOptionStorage;
67 class FloatOptionInfo;
68 class FloatOptionStorage;
69 class StringOptionInfo;
70 class StringOptionStorage;
71
72 /*! \addtogroup module_options
73  * \{
74  */
75
76 /*! \brief
77  * Specifies an option that provides boolean values.
78  *
79  * Example:
80  * \code
81    bool  bPBC;
82    using gmx::BooleanOption;
83    options.addOption(BooleanOption("pbc").store(&bPBC));
84  * \endcode
85  *
86  * Public methods in this class do not throw.
87  *
88  * \inpublicapi
89  */
90 class BooleanOption : public OptionTemplate<bool, BooleanOption>
91 {
92     public:
93         //! OptionInfo subclass corresponding to this option type.
94         typedef BooleanOptionInfo InfoType;
95
96         //! Initializes an option with the given name.
97         explicit BooleanOption(const char *name) : MyBase(name) {}
98
99     private:
100         //! Creates a BooleanOptionStorage object.
101         virtual AbstractOptionStoragePointer createStorage() const;
102 };
103
104 /*! \brief
105  * Specifies an option that provides integer values.
106  *
107  * Examples:
108  * \code
109    using gmx::IntegerOption;
110    // Simple option
111    int  rcut = 0;
112    options.addOption(IntegerOption("rcut").store(&rcut));
113    // Vector-valued option
114    int  box[3] = {1, 1, 1};  // Default value
115    options.addOption(IntegerOption("box").store(box).vector());
116  * \endcode
117  *
118  * Public methods in this class do not throw.
119  *
120  * \inpublicapi
121  */
122 class IntegerOption : public OptionTemplate<int, IntegerOption>
123 {
124     public:
125         //! OptionInfo subclass corresponding to this option type.
126         typedef IntegerOptionInfo InfoType;
127
128         //! Initializes an option with the given name.
129         explicit IntegerOption(const char *name) : MyBase(name) {}
130
131         /*! \brief
132          * Sets the option to return a vector value.
133          *
134          * A vector value returns a fixed number of values, the default being
135          * three (can be changed with valueCount()).  However, it also accepts
136          * a single value, in which case the value is used to fill the whole
137          * vector.
138          */
139         MyClass &vector() { setVector(); return me(); }
140
141     private:
142         //! Creates an IntegerOptionStorage object.
143         virtual AbstractOptionStoragePointer createStorage() const;
144
145         /*! \brief
146          * Needed to initialize IntegerOptionStorage from this class without
147          * otherwise unnecessary accessors.
148          */
149         friend class IntegerOptionStorage;
150 };
151
152 /*! \brief
153  * Specifies an option that provides 64-bit integer values.
154  *
155  * Public methods in this class do not throw.
156  *
157  * \see IntegerOption
158  *
159  * \inpublicapi
160  */
161 class Int64Option : public OptionTemplate<gmx_int64_t, Int64Option>
162 {
163     public:
164         //! OptionInfo subclass corresponding to this option type.
165         typedef Int64OptionInfo InfoType;
166
167         //! Initializes an option with the given name.
168         explicit Int64Option(const char *name) : MyBase(name) {}
169
170     private:
171         //! Creates an Int64OptionStorage object.
172         virtual AbstractOptionStoragePointer createStorage() const;
173
174         /*! \brief
175          * Needed to initialize Int64OptionStorage from this class without
176          * otherwise unnecessary accessors.
177          */
178         friend class Int64OptionStorage;
179 };
180
181 /*! \brief
182  * Specifies an option that provides floating-point (double) values.
183  *
184  * Public methods in this class do not throw.
185  *
186  * \inpublicapi
187  */
188 class DoubleOption : public OptionTemplate<double, DoubleOption>
189 {
190     public:
191         //! OptionInfo subclass corresponding to this option type.
192         typedef DoubleOptionInfo InfoType;
193
194         //! Initializes an option with the given name.
195         explicit DoubleOption(const char *name) : MyBase(name), bTime_(false)
196         {
197         }
198
199         //! \copydoc IntegerOption::vector()
200         MyClass &vector() { setVector(); return me(); }
201         /*! \brief
202          * Marks this option as providing a time value whose unit can be changed.
203          *
204          * By itself, this option does nothing.  It marks the option as a time
205          * value such that TimeUnitManager::scaleTimeOptions() can process it.
206          * In typical cases, \Gromacs scales the time options just before
207          * Options::finish() has been called, so the option value is only
208          * available after all option values have been processed.
209          * All values in the program are in ps (including any default value);
210          * user-provided values are scaled according to the time unit set in
211          * TimeUnitManager.
212          */
213         MyClass &timeValue() { bTime_ = true; return me(); }
214
215     private:
216         //! Creates a DoubleOptionStorage object.
217         virtual AbstractOptionStoragePointer createStorage() const;
218
219         bool bTime_;
220
221         /*! \brief
222          * Needed to initialize DoubleOptionStorage from this class without
223          * otherwise unnecessary accessors.
224          */
225         friend class DoubleOptionStorage;
226 };
227
228 /*! \brief
229  * Specifies an option that provides floating-point (float) values.
230  *
231  * Public methods in this class do not throw.
232  *
233  * \see DoubleOption
234  *
235  * \inpublicapi
236  */
237 class FloatOption : public OptionTemplate<float, FloatOption>
238 {
239     public:
240         //! OptionInfo subclass corresponding to this option type.
241         typedef FloatOptionInfo InfoType;
242
243         //! Initializes an option with the given name.
244         explicit FloatOption(const char *name) : MyBase(name), bTime_(false)
245         {
246         }
247
248         //! \copydoc IntegerOption::vector()
249         MyClass &vector() { setVector(); return me(); }
250         //! \copydoc DoubleOption::timeValue()
251         MyClass &timeValue() { bTime_ = true; return me(); }
252
253     private:
254         //! Creates a FloatOptionStorage object.
255         virtual AbstractOptionStoragePointer createStorage() const;
256
257         bool bTime_;
258
259         /*! \brief
260          * Needed to initialize FloatOptionStorage from this class without
261          * otherwise unnecessary accessors.
262          */
263         friend class FloatOptionStorage;
264 };
265
266 /*! \brief
267  * Specifies an option that provides string values.
268  *
269  * Examples:
270  * \code
271    using gmx::StringOption;
272    // Simple option
273    std::string  str;
274    options.addOption(StringOption("str").store(&str));
275    // Option that only accepts predefined values
276    const char * const  allowed[] = { "atom", "residue", "molecule" };
277    std::string  str;
278    int          type;
279    options.addOption(StringOption("type").enumValue(allowed).store(&str)
280                         .storeEnumIndex(&type));
281  * \endcode
282  *
283  * Public methods in this class do not throw.
284  *
285  * \inpublicapi
286  */
287 class StringOption : public OptionTemplate<std::string, StringOption>
288 {
289     public:
290         //! OptionInfo subclass corresponding to this option type.
291         typedef StringOptionInfo InfoType;
292
293         //! Initializes an option with the given name.
294         explicit StringOption(const char *name)
295             : MyBase(name), enumValues_(NULL), enumValuesCount_(0),
296               defaultEnumIndex_(-1), enumIndexStore_(NULL)
297         {
298         }
299
300         /*! \brief
301          * Sets the option to only accept one of a fixed set of strings.
302          *
303          * \param[in] values  Array of strings to accept.
304          *
305          * Also accepts prefixes of the strings; if a prefix matches more than
306          * one of the possible strings, the shortest one is used (in a tie, the
307          * first one is).
308          *
309          * It is not possible to provide multiple values for an option with
310          * this property set, i.e., valueCount() and similar attributes cannot
311          * be set.
312          *
313          * The strings are copied once the option is created.
314          */
315         template <size_t count>
316         MyClass &enumValue(const char *const (&values)[count])
317         {
318             GMX_ASSERT(enumValues_ == NULL,
319                        "Multiple sets of enumerated values specified");
320             enumValues_      = values;
321             enumValuesCount_ = count;
322             return me();
323         }
324         /*! \brief
325          * Sets the option to only accept one of a fixed set of strings.
326          *
327          * \param[in] values  Array of strings to accept, with a NULL pointer
328          *      following the last string.
329          *
330          * Works otherwise as the array version, but accepts a pointer to
331          * an array of undetermined length.  The end of the array is indicated
332          * by a NULL pointer in the array.
333          *
334          * \see enumValue()
335          */
336         MyClass &enumValueFromNullTerminatedArray(const char *const *values)
337         {
338             GMX_ASSERT(enumValues_ == NULL,
339                        "Multiple sets of enumerated values specified");
340             enumValues_      = values;
341             enumValuesCount_ = -1;
342             return me();
343         }
344         /*! \brief
345          * Sets the default value using an index into the enumeration table.
346          *
347          * Cannot be specified without enumValue().
348          */
349         MyClass &defaultEnumIndex(int index)
350         {
351             GMX_ASSERT(index >= 0, "Invalid enumeration index");
352             defaultEnumIndex_ = index;
353             return me();
354         }
355         /*! \brief
356          * Stores the index of the selected value into the provided memory
357          * location.
358          *
359          * The index (zero-based) of the selected value in the array \p values
360          * provided to enumValues() is written into \p *store after the
361          * option gets its value.  If the option has not been provided,
362          * and there is no default value, -1 is stored.
363          *
364          * Cannot be specified without enumValue().
365          *
366          * \todo
367          * Implement this such that it is also possible to store the value
368          * directly into a real enum type.
369          */
370         MyClass &storeEnumIndex(int *store)
371         { enumIndexStore_ = store; return me(); }
372
373     private:
374         //! Creates a StringOptionStorage object.
375         virtual AbstractOptionStoragePointer createStorage() const;
376
377         const char *const      *enumValues_;
378         int                     enumValuesCount_;
379         int                     defaultEnumIndex_;
380         int                    *enumIndexStore_;
381
382         /*! \brief
383          * Needed to initialize StringOptionStorage from this class without
384          * otherwise unnecessary accessors.
385          */
386         friend class StringOptionStorage;
387 };
388
389 /*! \brief
390  * Wrapper class for accessing boolean option information.
391  *
392  * \inpublicapi
393  */
394 class BooleanOptionInfo : public OptionInfo
395 {
396     public:
397         //! Creates an option info object for the given option.
398         explicit BooleanOptionInfo(BooleanOptionStorage *option);
399
400         //! Returns the default value for this option.
401         bool defaultValue() const;
402
403     private:
404         const BooleanOptionStorage &option() const;
405 };
406
407 /*! \brief
408  * Wrapper class for accessing integer option information.
409  *
410  * \inpublicapi
411  */
412 class IntegerOptionInfo : public OptionInfo
413 {
414     public:
415         //! Creates an option info object for the given option.
416         explicit IntegerOptionInfo(IntegerOptionStorage *option);
417 };
418
419 /*! \brief
420  * Wrapper class for accessing 64-bit integer option information.
421  *
422  * \inpublicapi
423  */
424 class Int64OptionInfo : public OptionInfo
425 {
426     public:
427         //! Creates an option info object for the given option.
428         explicit Int64OptionInfo(Int64OptionStorage *option);
429 };
430
431 /*! \brief
432  * Wrapper class for accessing floating-point option information.
433  *
434  * \inpublicapi
435  */
436 class DoubleOptionInfo : public OptionInfo
437 {
438     public:
439         //! Creates an option info object for the given option.
440         explicit DoubleOptionInfo(DoubleOptionStorage *option);
441
442         //! Whether the option specifies a time value.
443         bool isTime() const;
444
445         /*! \brief
446          * Sets a scale factor for user-provided values.
447          *
448          * Any user-provided value is scaled by the provided factor.
449          * Programmatically set default values are not scaled.
450          * If called multiple times, later calls override the previously set
451          * value.  In other words, the scaling is not cumulative.
452          */
453         void setScaleFactor(double factor);
454
455     private:
456         DoubleOptionStorage &option();
457         const DoubleOptionStorage &option() const;
458 };
459
460 /*! \brief
461  * Wrapper class for accessing floating-point option information.
462  *
463  * \inpublicapi
464  */
465 class FloatOptionInfo : public OptionInfo
466 {
467     public:
468         //! Creates an option info object for the given option.
469         explicit FloatOptionInfo(FloatOptionStorage *option);
470
471         //! Whether the option specifies a time value.
472         bool isTime() const;
473
474         //! \copydoc DoubleOptionInfo::setScaleFactor()
475         void setScaleFactor(double factor);
476
477     private:
478         FloatOptionStorage &option();
479         const FloatOptionStorage &option() const;
480 };
481
482 /*! \brief
483  * Wrapper class for accessing string option information.
484  *
485  * \inpublicapi
486  */
487 class StringOptionInfo : public OptionInfo
488 {
489     public:
490         //! Creates an option info object for the given option.
491         explicit StringOptionInfo(StringOptionStorage *option);
492
493         /*! \brief
494          * Whether this option accepts an enumerated set of values.
495          *
496          * Returns true if StringOption::enumValues() was used when creating
497          * this option.
498          */
499         bool isEnumerated() const;
500         /*! \brief
501          * Returns the set of allowed values for this option.
502          *
503          * Returns an empty vector if isEnumerated() returns false.
504          */
505         const std::vector<std::string> &allowedValues() const;
506
507     private:
508         StringOptionStorage &option();
509         const StringOptionStorage &option() const;
510 };
511
512 /*! \typedef RealOption
513  * \brief
514  * Typedef for either DoubleOption or FloatOption, depending on precision.
515  *
516  * Generally, new would be better using DoubleOption, but this is provided for
517  * cases where the output value needs to be of type `real` for some reason.
518  */
519 /*! \typedef RealOptionInfo
520  * \brief
521  * Typedef for either DoubleOptionInfo or FloatOptionInfo, depending on precision.
522  *
523  * Generally, new would be better using DoubleOption, but this is provided for
524  * cases where the output value needs to be of type `real` for some reason.
525  */
526 #ifdef GMX_DOUBLE
527 typedef DoubleOption     RealOption;
528 typedef DoubleOptionInfo RealOptionInfo;
529 #else
530 typedef FloatOption      RealOption;
531 typedef FloatOptionInfo  RealOptionInfo;
532 #endif
533
534 /*!\}*/
535
536 } // namespace gmx
537
538 #endif