2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2010-2017, The GROMACS development team.
5 * Copyright (c) 2019,2021, by the GROMACS development team, led by
6 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7 * and including many others, as listed in the AUTHORS file in the
8 * top-level source directory and at http://www.gromacs.org.
10 * GROMACS is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1
13 * of the License, or (at your option) any later version.
15 * GROMACS is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with GROMACS; if not, see
22 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 * If you want to redistribute modifications to GROMACS, please
26 * consider that scientific software is very special. Version
27 * control is crucial - bugs must be traceable. We will be happy to
28 * consider code for inclusion in the official distribution, but
29 * derived work must not be called official GROMACS. Details are found
30 * in the README & COPYING files - if they are missing, get the
31 * official version at http://www.gromacs.org.
33 * To help us fund GROMACS development, we humbly ask that you cite
34 * the research papers on the package. Check out http://www.gromacs.org.
38 * Defines gmx::AbstractOption, gmx::OptionTemplate and gmx::OptionInfo.
40 * This header defines base classes for option settings that are used with
41 * Options::addOption(). These classes implement the "named parameter"
42 * idiom for specifying option properties.
44 * These classes also take care of creating and setting up the actual option
47 * This header is needed directly only when implementing new option types,
48 * but methods of OptionTemplate are visible even to the normal user through
51 * \author Teemu Murtola <teemu.murtola@gmail.com>
53 * \ingroup module_options
55 #ifndef GMX_OPTIONS_ABSTRACTOPTION_H
56 #define GMX_OPTIONS_ABSTRACTOPTION_H
62 #include "gromacs/utility/classhelpers.h"
64 #include "optionflags.h"
69 class AbstractOptionStorage;
71 class OptionStorageTemplate;
72 class OptionManagerContainer;
77 class OptionSectionImpl;
81 * Abstract base class for specifying option properties.
83 * Concrete classes should normally not derive directly from this class,
84 * but from OptionTemplate instead. Classes derived from this class
85 * are mainly designed to implement the "named parameter" idiom. For
86 * efficiency and clarity, these classes should only store values provided to
87 * them. All error checking and memory management should be postponed to the
88 * point when the actual option is created.
90 * Subclasses should override createStorage() to create the correct type
91 * of storage object. If they use their own info type derived from OptionInfo,
92 * they should also have a public typedef \c InfoType that specifies that
93 * info type. This is required for Options::addOption() to return the correct
96 * \ingroup module_options
101 // Virtual only for completeness, in normal use should not be needed.
102 virtual ~AbstractOption() {}
106 //! Initializes the name and default values for an option.
107 explicit AbstractOption(const char* name) :
108 minValueCount_(1), maxValueCount_(1), name_(name), descr_(nullptr), storeIsSet_(nullptr)
113 * Creates a default storage object for the option.
115 * \param[in] managers Manager container (unused if the option does
116 * not use a manager).
117 * \returns The created storage object.
118 * \throws APIError if invalid option settings have been provided.
120 * This method is called by Options::addOption() when initializing an
121 * option from the settings.
123 * Derived classes should implement the method to create an actual
124 * storage object and populate it with correct values.
125 * They should also throw APIError if they detect problems.
127 * Should only be called by Options::addOption().
129 * The ownership of the return value is passed, but is not using a
130 * smart pointer to avoid introducing such a dependency in an installed
131 * header. The implementation will always consist of a single `new`
132 * call and returning that value, and the caller always immediately
133 * wraps the pointer in a smart pointer, so there is not exception
136 virtual AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const = 0;
138 //! Sets the description for the option.
139 void setDescription(const char* descr) { descr_ = descr; }
140 //! Sets the storage location for whether the option is set.
141 void setStoreIsSet(bool* store) { storeIsSet_ = store; }
142 //! Sets a flag for the option.
143 void setFlag(OptionFlag flag) { flags_.set(flag); }
144 //! Clears a flag for the option.
145 void clearFlag(OptionFlag flag) { flags_.clear(flag); }
146 //! Sets or clears a flag for the option.
147 void setFlag(OptionFlag flag, bool bSet) { flags_.set(flag, bSet); }
148 //! Returns true if the option is vector-valued.
149 bool isVector() const { return hasFlag(efOption_Vector); }
151 * Sets the option to be vector-valued.
153 * This method is provided for convenience to make management of value
154 * counts easier. In order to implement a vector-valued option, the
155 * class derived from AbstractOption should expose a method that calls
156 * this method, and the storage object derived from
157 * AbstractOptionStorage should check isVector().
158 * If only a single value is provided, the storage object should fill
159 * the whole vector with that value.
161 * The length of the vector (the value of maxValueCount_) must be
162 * fixed. The default length is 3 elements.
166 setFlag(efOption_Vector);
168 if (maxValueCount_ == 1)
173 //! Sets the required number of values for the option.
174 void setValueCount(int count)
176 if (!hasFlag(efOption_Vector))
178 minValueCount_ = count;
180 maxValueCount_ = count;
183 //! Minimum number of values required for the option.
185 //! Maximum number of values allowed for the option.
190 //! Returns true if a flag has been set.
191 bool hasFlag(OptionFlag flag) const { return flags_.test(flag); }
194 //! Pointer to description of the option.
200 * Needed to initialize an AbstractOptionStorage object from this class
201 * without otherwise unnecessary accessors.
203 friend class AbstractOptionStorage;
204 //! Needed to be able to call createStorage().
205 friend class internal::OptionSectionImpl;
209 * Templated base class for constructing concrete option settings classes.
211 * \tparam T Assignable type that stores a single option value.
212 * \tparam U Type of the derived class.
214 * This template is used as a base class like this:
216 class ConcreteOption : public OptionTemplate<int, ConcreteOption>
220 * All public functions in this class return \c *this casted to a reference to
221 * \p U. They do not throw.
223 * For examples of how to use classes derived from this class, see the class
224 * documentation for Options.
227 * \ingroup module_options
229 template<typename T, class U>
230 class OptionTemplate : public AbstractOption
233 //! Type that stores a single option value.
235 //! Alias for the derived class type.
239 * Sets a description for the option.
241 * \param[in] descr Description to set.
243 * String in \p descr is copied when the option is created.
245 MyClass& description(const char* descr)
247 setDescription(descr);
250 //! Hides the option from normal help output.
251 MyClass& hidden(bool bHidden = true)
253 setFlag(efOption_Hidden, bHidden);
257 * Requires the option to be specified explicitly.
259 * Note that if you specify defaultValue() together with required(),
260 * the user is not required to explicitly provide the option.
261 * In this case, required() only affects possible help output.
263 MyClass& required(bool bRequired = true)
265 setFlag(efOption_Required, bRequired);
268 //! Allows the option to be specified multiple times.
269 MyClass& allowMultiple(bool bMulti = true)
271 setFlag(efOption_MultipleTimes, bMulti);
274 //! Requires exactly \p count values for the option.
275 MyClass& valueCount(int count)
277 setValueCount(count);
280 //! Allows any number of values for the option.
281 MyClass& multiValue(bool bMulti = true)
291 * Sets a default value for the option.
293 * \param[in] defaultValue Default value.
295 * If the option is never set, the default value is copied to the
296 * assigned storage. Note that if the option is not set and there
297 * is no default value, the storage is not altered, which can also be
298 * used to provide a default value. The latter method has to be used
299 * if the option can take multiple values.
301 * \p defaultValue is copied when the option is created.
303 MyClass& defaultValue(const T& defaultValue)
305 defaultValue_ = &defaultValue;
309 * Sets a default value for the option when it is set.
311 * \param[in] defaultValue Default value.
313 * This value is used if the option is set, but no value is provided.
314 * If the option is never set, the value set with defaultValue() is
315 * used. Can only be used for options that accept a single value.
317 * \p defaultValue is copied when the option is created.
319 MyClass& defaultValueIfSet(const T& defaultValue)
321 defaultValueIfSet_ = &defaultValue;
325 * Stores value(s) in memory pointed by \p store.
327 * \param[in] store Storage for option value(s).
329 * The caller is responsible for allocating enough memory such that
330 * the any allowed number of values fits into the array pointed by
331 * \p store. If there is no maximum allowed number or if the maximum
332 * is inconveniently large, storeVector() should be used.
334 * For information on when values are available in the storage, see
337 * The pointer provided should remain valid as long as the associated
338 * Options object exists.
340 MyClass& store(T* store)
346 * Stores number of values in the value pointed by \p countptr.
348 * \param[in] countptr Storage for the number of values.
350 * For information on when values are available in the storage, see
353 * The pointers provided should remain valid as long as the associated
354 * Options object exists.
356 MyClass& storeCount(int* countptr)
358 countptr_ = countptr;
362 * Stores option values in the provided vector.
364 * \param[in] store Vector to store option values in.
366 * Values are added to the vector after each successful set of values
367 * is parsed. Note that for some options, the value may be changed
368 * later, and is only guaranteed to be correct after Options::finish()
371 * The pointer provided should remain valid as long as the associated
372 * Options object exists.
374 MyClass& storeVector(std::vector<T>* store)
376 storeVector_ = store;
380 * Stores whether the option was explicitly set.
382 * \param[in] store Variable to store the flag in.
384 * The value is set to `false` on creation of the option, and to `true`
385 * as soon as a value is assigned to the option. A default value does
386 * not set the flag to `true`, but assignment that uses
387 * defaultValueIfSet() does.
389 * The pointer provided should remain valid as long as the associated
390 * Options object exists.
392 MyClass& storeIsSet(bool* store)
394 setStoreIsSet(store);
400 //! Alias for the template class for use in base classes.
401 typedef OptionTemplate<T, U> MyBase;
403 //! Initializes the name and default values for an option.
404 explicit OptionTemplate(const char* name) :
405 AbstractOption(name),
406 defaultValue_(nullptr),
407 defaultValueIfSet_(nullptr),
410 storeVector_(nullptr)
415 * Returns a pointer to user-specified default value, or NULL if there
418 const T* defaultValue() const { return defaultValue_; }
420 * Returns a pointer to user-specified default value, or NULL if there
423 const T* defaultValueIfSet() const { return defaultValueIfSet_; }
425 * Returns a pointer to the storage location, or NULL if none specified.
427 T* store() const { return store_; }
429 * Returns a pointer to the storage vector, or NULL if none specified.
431 std::vector<T>* storeVector() const { return storeVector_; }
432 //! Returns \p *this casted into MyClass to reduce typing.
433 MyClass& me() { return static_cast<MyClass&>(*this); }
437 const T* defaultValue_;
438 const T* defaultValueIfSet_;
441 std::vector<T>* storeVector_;
444 * Needed to initialize storage from this class without otherwise
445 * unnecessary accessors.
447 friend class OptionStorageTemplate<T>;
451 * Gives information and allows modifications to an option after creation.
453 * When an option is added with Options::addOption(), an object of a subclass
454 * of OptionInfo is returned. This object can be later used to access
455 * information about the option. Non-const methods also allow later changing
456 * (some of) the option settings provided at initialization time.
457 * The properties accessible/modifiable through this interface are implemented
458 * based on need, and may not be implemented for all cases.
461 * This class is also used by OptionsVisitor and OptionsModifyingVisitor as
462 * the interface that allows querying/modifying each visited option.
465 * This class isolates the details of the internal option implementation from
466 * callers. Although this class is a simple reference to the underlying
467 * implementation, it is implemented as non-copyable to allow const/non-const
468 * status of a reference to this class to indicate whether modifications are
469 * allowed. Otherwise, separate classes would be needed for access and
470 * modification, complicating the implementation. In the implementation,
471 * there is always a single OptionInfo instance referring to one option.
472 * The underlying implementation object always owns this instance, and only
473 * references are passed to callers.
475 * \see Options::addOption()
477 * \see OptionsVisitor
478 * \see OptionsModifyingVisitor
482 * \ingroup module_options
487 virtual ~OptionInfo();
490 * Test whether the option is of a particular type.
492 * \tparam InfoType Option type to test for. Should be a class derived
495 template<class InfoType>
498 return toType<InfoType>() != nullptr;
501 * Convert the info object to a particular type if the type is correct.
503 * \tparam InfoType Option type to convert to. Should be a class
504 * derived from OptionInfo.
505 * \retval this converted to a pointer to \p InfoType, or NULL if the
506 * conversion is not possible.
508 template<class InfoType>
511 return dynamic_cast<InfoType*>(this);
513 //! \copydoc toType()
514 template<class InfoType>
515 const InfoType* toType() const
517 return dynamic_cast<const InfoType*>(this);
520 //! Returns true if the option has been set.
522 //! Returns true if the option is a hidden option.
523 bool isHidden() const;
524 //! Returns true if the option is required.
525 bool isRequired() const;
526 //! Returns the minimum number of values that this option accepts.
527 int minValueCount() const;
528 //! Returns the maximum number of values that this option accepts.
529 int maxValueCount() const;
530 //! Returns the name of the option.
531 const std::string& name() const;
532 //! Returns the type of the option as a string.
533 std::string type() const;
534 //! Returns the description of the option.
535 std::string formatDescription() const;
538 * Returns the default value(s) of the option.
540 * The returned values should all be of the same type, but returning
541 * each as a separate any is currently simpler.
543 * Currently, this can only be called before option values have been
546 std::vector<Any> defaultValues() const;
548 * Returns the default value(s) of the option as strings.
550 * If there is no default value, but defaultValueIfSet() is set, that
551 * is returned instead.
553 * Currently, this can only be called before option values have been
556 std::vector<std::string> defaultValuesAsStrings() const;
558 * Converts given values to native representation for this option.
560 * For example, strings are parsed to the type that is actually used to
563 * The return value only depends on the option type, not on the current
564 * value of the option, and the current value in the option is not
567 std::vector<Any> normalizeValues(const std::vector<Any>& values) const;
572 * Wraps a given option object.
576 explicit OptionInfo(AbstractOptionStorage* option);
578 //! Returns the wrapped option storage object.
579 AbstractOptionStorage& option() { return option_; }
580 //! Returns the wrapped option storage object.
581 const AbstractOptionStorage& option() const { return option_; }
585 //! The wrapped option.
586 AbstractOptionStorage& option_;
588 GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo);