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