Fix tune_pme
[gromacs.git] / src / gromacs / options / abstractoption.h
blob575cd6efaddffba760057f6e1ef5f8fff885bfb4
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, 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.
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.
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.
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.
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.
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.
35 /*! \file
36 * \brief
37 * Defines gmx::AbstractOption, gmx::OptionTemplate and gmx::OptionInfo.
39 * This header defines base classes for option settings that are used with
40 * Options::addOption(). These classes implement the "named parameter"
41 * idiom for specifying option properties.
43 * These classes also take care of creating and setting up the actual option
44 * objects.
46 * This header is needed directly only when implementing new option types,
47 * but methods of OptionTemplate are visible even to the normal user through
48 * its subclasses.
50 * \author Teemu Murtola <teemu.murtola@gmail.com>
51 * \inlibraryapi
52 * \ingroup module_options
54 #ifndef GMX_OPTIONS_ABSTRACTOPTION_H
55 #define GMX_OPTIONS_ABSTRACTOPTION_H
57 #include <string>
58 #include <vector>
60 #include "gromacs/options/optionflags.h"
61 #include "gromacs/utility/classhelpers.h"
63 namespace gmx
66 class AbstractOptionStorage;
67 template <typename T> class OptionStorageTemplate;
68 class OptionManagerContainer;
69 class Variant;
71 namespace internal
73 class OptionSectionImpl;
76 /*! \brief
77 * Abstract base class for specifying option properties.
79 * Concrete classes should normally not derive directly from this class,
80 * but from OptionTemplate instead. Classes derived from this class
81 * are mainly designed to implement the "named parameter" idiom. For
82 * efficiency and clarity, these classes should only store values provided to
83 * them. All error checking and memory management should be postponed to the
84 * point when the actual option is created.
86 * Subclasses should override createStorage() to create the correct type
87 * of storage object. If they use their own info type derived from OptionInfo,
88 * they should also have a public typedef \c InfoType that specifies that
89 * info type. This is required for Options::addOption() to return the correct
90 * info type.
92 * \ingroup module_options
94 class AbstractOption
96 public:
97 // Virtual only for completeness, in normal use should not be needed.
98 virtual ~AbstractOption() { }
100 protected:
101 /*! \cond libapi */
102 //! Initializes the name and default values for an option.
103 explicit AbstractOption(const char *name)
104 : minValueCount_(1), maxValueCount_(1),
105 name_(name), descr_(nullptr), storeIsSet_(nullptr)
108 /*! \brief
109 * Creates a default storage object for the option.
111 * \param[in] managers Manager container (unused if the option does
112 * not use a manager).
113 * \returns The created storage object.
114 * \throws APIError if invalid option settings have been provided.
116 * This method is called by Options::addOption() when initializing an
117 * option from the settings.
119 * Derived classes should implement the method to create an actual
120 * storage object and populate it with correct values.
121 * They should also throw APIError if they detect problems.
123 * Should only be called by Options::addOption().
125 * The ownership of the return value is passed, but is not using a
126 * smart pointer to avoid introducing such a dependency in an installed
127 * header. The implementation will always consist of a single `new`
128 * call and returning that value, and the caller always immediately
129 * wraps the pointer in a smart pointer, so there is not exception
130 * safety issue.
132 virtual AbstractOptionStorage *createStorage(
133 const OptionManagerContainer &managers) const = 0;
135 //! Sets the description for the option.
136 void setDescription(const char *descr) { descr_ = descr; }
137 //! Sets the storage location for whether the option is set.
138 void setStoreIsSet(bool *store) { storeIsSet_ = store; }
139 //! Sets a flag for the option.
140 void setFlag(OptionFlag flag) { flags_.set(flag); }
141 //! Clears a flag for the option.
142 void clearFlag(OptionFlag flag) { flags_.clear(flag); }
143 //! Sets or clears a flag for the option.
144 void setFlag(OptionFlag flag, bool bSet) { flags_.set(flag, bSet); }
145 //! Returns true if the option is vector-valued.
146 bool isVector() const { return hasFlag(efOption_Vector); }
147 /*! \brief
148 * Sets the option to be vector-valued.
150 * This method is provided for convenience to make management of value
151 * counts easier. In order to implement a vector-valued option, the
152 * class derived from AbstractOption should expose a method that calls
153 * this method, and the storage object derived from
154 * AbstractOptionStorage should check isVector().
155 * If only a single value is provided, the storage object should fill
156 * the whole vector with that value.
158 * The length of the vector (the value of maxValueCount_) must be
159 * fixed. The default length is 3 elements.
161 void setVector()
163 setFlag(efOption_Vector);
164 minValueCount_ = 1;
165 if (maxValueCount_ == 1)
167 maxValueCount_ = 3;
170 //! Sets the required number of values for the option.
171 void setValueCount(int count)
173 if (!hasFlag(efOption_Vector))
175 minValueCount_ = count;
177 maxValueCount_ = count;
180 //! Minimum number of values required for the option.
181 int minValueCount_;
182 //! Maximum number of values allowed for the option.
183 int maxValueCount_;
184 //! \endcond
186 private:
187 //! Returns true if a flag has been set.
188 bool hasFlag(OptionFlag flag) const { return flags_.test(flag); }
190 const char *name_;
191 //! Pointer to description of the option.
192 const char *descr_;
193 OptionFlags flags_;
194 bool *storeIsSet_;
196 /*! \brief
197 * Needed to initialize an AbstractOptionStorage object from this class
198 * without otherwise unnecessary accessors.
200 friend class AbstractOptionStorage;
201 //! Needed to be able to call createStorage().
202 friend class internal::OptionSectionImpl;
205 /*! \brief
206 * Templated base class for constructing concrete option settings classes.
208 * \tparam T Assignable type that stores a single option value.
209 * \tparam U Type of the derived class.
211 * This template is used as a base class like this:
212 * \code
213 class ConcreteOption : public OptionTemplate<int, ConcreteOption>
215 * \endcode
217 * All public functions in this class return \c *this casted to a reference to
218 * \p U. They do not throw.
220 * For examples of how to use classes derived from this class, see the class
221 * documentation for Options.
223 * \inlibraryapi
224 * \ingroup module_options
226 template <typename T, class U>
227 class OptionTemplate : public AbstractOption
229 public:
230 //! Type that stores a single option value.
231 typedef T ValueType;
232 //! Alias for the derived class type.
233 typedef U MyClass;
235 /*! \brief
236 * Sets a description for the option.
238 * \param[in] descr Description to set.
240 * String in \p descr is copied when the option is created.
242 MyClass &description(const char *descr)
243 { setDescription(descr); return me(); }
244 //! Hides the option from normal help output.
245 MyClass &hidden(bool bHidden = true)
246 { setFlag(efOption_Hidden, bHidden); return me(); }
247 /*! \brief
248 * Requires the option to be specified explicitly.
250 * Note that if you specify defaultValue() together with required(),
251 * the user is not required to explicitly provide the option.
252 * In this case, required() only affects possible help output.
254 MyClass &required(bool bRequired = true)
255 { setFlag(efOption_Required, bRequired); return me(); }
256 //! Allows the option to be specified multiple times.
257 MyClass &allowMultiple(bool bMulti = true)
258 { setFlag(efOption_MultipleTimes, bMulti); return me(); }
259 //! Requires exactly \p count values for the option.
260 MyClass &valueCount(int count) { setValueCount(count); return me(); }
261 //! Allows any number of values for the option.
262 MyClass &multiValue(bool bMulti = true)
263 { if (bMulti) { maxValueCount_ = -1; } return me(); }
265 /*! \brief
266 * Sets a default value for the option.
268 * \param[in] defaultValue Default value.
270 * If the option is never set, the default value is copied to the
271 * assigned storage. Note that if the option is not set and there
272 * is no default value, the storage is not altered, which can also be
273 * used to provide a default value. The latter method has to be used
274 * if the option can take multiple values.
276 * \p defaultValue is copied when the option is created.
278 MyClass &defaultValue(const T &defaultValue)
279 { defaultValue_ = &defaultValue; return me(); }
280 /*! \brief
281 * Sets a default value for the option when it is set.
283 * \param[in] defaultValue Default value.
285 * This value is used if the option is set, but no value is provided.
286 * If the option is never set, the value set with defaultValue() is
287 * used. Can only be used for options that accept a single value.
289 * \p defaultValue is copied when the option is created.
291 MyClass &defaultValueIfSet(const T &defaultValue)
292 { defaultValueIfSet_ = &defaultValue; return me(); }
293 /*! \brief
294 * Stores value(s) in memory pointed by \p store.
296 * \param[in] store Storage for option value(s).
298 * The caller is responsible for allocating enough memory such that
299 * the any allowed number of values fits into the array pointed by
300 * \p store. If there is no maximum allowed number or if the maximum
301 * is inconveniently large, storeVector() should be used.
303 * For information on when values are available in the storage, see
304 * storeVector().
306 * The pointer provided should remain valid as long as the associated
307 * Options object exists.
309 MyClass &store(T *store)
310 { store_ = store; return me(); }
311 /*! \brief
312 * Stores number of values in the value pointed by \p countptr.
314 * \param[in] countptr Storage for the number of values.
316 * For information on when values are available in the storage, see
317 * storeVector().
319 * The pointers provided should remain valid as long as the associated
320 * Options object exists.
322 MyClass &storeCount(int *countptr)
323 { countptr_ = countptr; return me(); }
324 /*! \brief
325 * Stores option values in the provided vector.
327 * \param[in] store Vector to store option values in.
329 * Values are added to the vector after each successful set of values
330 * is parsed. Note that for some options, the value may be changed
331 * later, and is only guaranteed to be correct after Options::finish()
332 * has been called.
334 * The pointer provided should remain valid as long as the associated
335 * Options object exists.
337 MyClass &storeVector(std::vector<T> *store)
338 { storeVector_ = store; return me(); }
339 /*! \brief
340 * Stores whether the option was explicitly set.
342 * \param[in] store Variable to store the flag in.
344 * The value is set to `false` on creation of the option, and to `true`
345 * as soon as a value is assigned to the option. A default value does
346 * not set the flag to `true`, but assignment that uses
347 * defaultValueIfSet() does.
349 * The pointer provided should remain valid as long as the associated
350 * Options object exists.
352 MyClass &storeIsSet(bool *store)
353 { setStoreIsSet(store); return me(); }
355 protected:
356 /*! \cond libapi */
357 //! Alias for the template class for use in base classes.
358 typedef OptionTemplate<T, U> MyBase;
360 //! Initializes the name and default values for an option.
361 explicit OptionTemplate(const char *name)
362 : AbstractOption(name),
363 defaultValue_(nullptr), defaultValueIfSet_(nullptr), store_(nullptr),
364 countptr_(nullptr), storeVector_(nullptr)
367 /*! \brief
368 * Returns a pointer to user-specified default value, or NULL if there
369 * is none.
371 const T *defaultValue() const { return defaultValue_; }
372 /*! \brief
373 * Returns a pointer to user-specified default value, or NULL if there
374 * is none.
376 const T *defaultValueIfSet() const { return defaultValueIfSet_; }
377 /*! \brief
378 * Returns a pointer to the storage location, or NULL if none specified.
380 T *store() const { return store_; }
381 /*! \brief
382 * Returns a pointer to the storage vector, or NULL if none specified.
384 std::vector<T> *storeVector() const { return storeVector_; }
385 //! Returns \p *this casted into MyClass to reduce typing.
386 MyClass &me() { return static_cast<MyClass &>(*this); }
387 //! \endcond
389 private:
390 const T *defaultValue_;
391 const T *defaultValueIfSet_;
392 T *store_;
393 int *countptr_;
394 std::vector<T> *storeVector_;
396 /*! \brief
397 * Needed to initialize storage from this class without otherwise
398 * unnecessary accessors.
400 friend class OptionStorageTemplate<T>;
403 /*! \brief
404 * Gives information and allows modifications to an option after creation.
406 * When an option is added with Options::addOption(), an object of a subclass
407 * of OptionInfo is returned. This object can be later used to access
408 * information about the option. Non-const methods also allow later changing
409 * (some of) the option settings provided at initialization time.
410 * The properties accessible/modifiable through this interface are implemented
411 * based on need, and may not be implemented for all cases.
413 * \if libapi
414 * This class is also used by OptionsVisitor and OptionsModifyingVisitor as
415 * the interface that allows querying/modifying each visited option.
416 * \endif
418 * This class isolates the details of the internal option implementation from
419 * callers. Although this class is a simple reference to the underlying
420 * implementation, it is implemented as non-copyable to allow const/non-const
421 * status of a reference to this class to indicate whether modifications are
422 * allowed. Otherwise, separate classes would be needed for access and
423 * modification, complicating the implementation. In the implementation,
424 * there is always a single OptionInfo instance referring to one option.
425 * The underlying implementation object always owns this instance, and only
426 * references are passed to callers.
428 * \see Options::addOption()
429 * \if libapi
430 * \see OptionsVisitor
431 * \see OptionsModifyingVisitor
432 * \endif
434 * \inpublicapi
435 * \ingroup module_options
437 class OptionInfo
439 public:
440 virtual ~OptionInfo();
442 /*! \brief
443 * Test whether the option is of a particular type.
445 * \tparam InfoType Option type to test for. Should be a class derived
446 * from OptionInfo.
448 template <class InfoType>
449 bool isType() const
451 return toType<InfoType>() != nullptr;
453 /*! \brief
454 * Convert the info object to a particular type if the type is correct.
456 * \tparam InfoType Option type to convert to. Should be a class
457 * derived from OptionInfo.
458 * \retval this converted to a pointer to \p InfoType, or NULL if the
459 * conversion is not possible.
461 template <class InfoType>
462 InfoType *toType()
464 return dynamic_cast<InfoType *>(this);
466 //! \copydoc toType()
467 template <class InfoType>
468 const InfoType *toType() const
470 return dynamic_cast<const InfoType *>(this);
473 //! Returns true if the option has been set.
474 bool isSet() const;
475 //! Returns true if the option is a hidden option.
476 bool isHidden() const;
477 //! Returns true if the option is required.
478 bool isRequired() const;
479 //! Returns the minimum number of values that this option accepts.
480 int minValueCount() const;
481 //! Returns the maximum number of values that this option accepts.
482 int maxValueCount() const;
483 //! Returns the name of the option.
484 const std::string &name() const;
485 //! Returns the type of the option as a string.
486 std::string type() const;
487 //! Returns the description of the option.
488 std::string formatDescription() const;
490 /*! \brief
491 * Returns the default value(s) of the option.
493 * The returned values should all be of the same type, but returning
494 * each as a separate variant is currently simpler.
496 * Currently, this can only be called before option values have been
497 * assigned.
499 std::vector<Variant> defaultValues() const;
500 /*! \brief
501 * Returns the default value(s) of the option as strings.
503 * If there is no default value, but defaultValueIfSet() is set, that
504 * is returned instead.
506 * Currently, this can only be called before option values have been
507 * assigned.
509 std::vector<std::string> defaultValuesAsStrings() const;
510 /*! \brief
511 * Converts given values to native representation for this option.
513 * For example, strings are parsed to the type that is actually used to
514 * store the options.
516 * The return value only depends on the option type, not on the current
517 * value of the option, and the current value in the option is not
518 * changed.
520 std::vector<Variant> normalizeValues(const std::vector<Variant> &values) const;
522 protected:
523 /*! \cond libapi */
524 /*! \brief
525 * Wraps a given option object.
527 * Does not throw.
529 explicit OptionInfo(AbstractOptionStorage *option);
531 //! Returns the wrapped option storage object.
532 AbstractOptionStorage &option() { return option_; }
533 //! Returns the wrapped option storage object.
534 const AbstractOptionStorage &option() const { return option_; }
535 //! \endcond
537 private:
538 //! The wrapped option.
539 AbstractOptionStorage &option_;
541 GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo);
544 } // namespace gmx
546 #endif