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