2 * This file is part of the GROMACS molecular simulation package.
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.
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.
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
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
50 * \author Teemu Murtola <teemu.murtola@gmail.com>
52 * \ingroup module_options
54 #ifndef GMX_OPTIONS_ABSTRACTOPTION_H
55 #define GMX_OPTIONS_ABSTRACTOPTION_H
60 #include "../utility/common.h"
62 #include "optionflags.h"
67 class AbstractOptionStorage;
68 template <typename T> class OptionStorageTemplate;
69 class OptionManagerContainer;
73 * Abstract base class for specifying option properties.
75 * Concrete classes should normally not derive directly from this class,
76 * but from OptionTemplate instead. Classes derived from this class
77 * are mainly designed to implement the "named parameter" idiom. For
78 * efficiency and clarity, these classes should only store values provided to
79 * them. All error checking and memory management should be postponed to the
80 * point when the actual option is created.
82 * Subclasses should override createStorage() to create the correct type
83 * of storage object. If they use their own info type derived from OptionInfo,
84 * they should also have a public typedef \c InfoType that specifies that
85 * info type. This is required for Options::addOption() to return the correct
88 * \ingroup module_options
93 // Virtual only for completeness, in normal use should not be needed.
94 virtual ~AbstractOption() { }
98 //! Initializes the name and default values for an option.
99 explicit AbstractOption(const char *name)
100 : minValueCount_(1), maxValueCount_(1),
101 name_(name), descr_(NULL)
105 * Creates a default storage object for the option.
107 * \param[in] managers Manager container (unused if the option does
108 * not use a manager).
109 * \returns The created storage object.
110 * \throws APIError if invalid option settings have been provided.
112 * This method is called by Options::addOption() when initializing an
113 * option from the settings.
115 * Derived classes should implement the method to create an actual
116 * storage object and populate it with correct values.
117 * They should also throw APIError if they detect problems.
119 * Should only be called by Options::addOption().
121 * The ownership of the return value is passed, but is not using a
122 * smart pointer to avoid introducing such a dependency in an installed
123 * header. The implementation will always consist of a single `new`
124 * call and returning that value, and the caller always immediately
125 * wraps the pointer in a smart pointer, so there is not exception
128 virtual AbstractOptionStorage *createStorage(
129 const OptionManagerContainer &managers) const = 0;
131 //! Sets the description for the option.
132 void setDescription(const char *descr) { descr_ = descr; }
133 //! Sets a flag for the option.
134 void setFlag(OptionFlag flag) { flags_.set(flag); }
135 //! Clears a flag for the option.
136 void clearFlag(OptionFlag flag) { flags_.clear(flag); }
137 //! Sets or clears a flag for the option.
138 void setFlag(OptionFlag flag, bool bSet) { flags_.set(flag, bSet); }
139 //! Returns true if the option is vector-valued.
140 bool isVector() const { return hasFlag(efOption_Vector); }
142 * Sets the option to be vector-valued.
144 * This method is provided for convenience to make management of value
145 * counts easier. In order to implement a vector-valued option, the
146 * class derived from AbstractOption should expose a method that calls
147 * this method, and the storage object derived from
148 * AbstractOptionStorage should check isVector().
149 * If only a single value is provided, the storage object should fill
150 * the whole vector with that value.
152 * The length of the vector (the value of maxValueCount_) must be
153 * fixed. The default length is 3 elements.
157 setFlag(efOption_Vector);
159 if (maxValueCount_ == 1)
164 //! Sets the required number of values for the option.
165 void setValueCount(int count)
167 if (!hasFlag(efOption_Vector))
169 minValueCount_ = count;
171 maxValueCount_ = count;
174 //! Minimum number of values required for the option.
176 //! Maximum number of values allowed for the option.
181 //! Returns true if a flag has been set.
182 bool hasFlag(OptionFlag flag) const { return flags_.test(flag); }
185 //! Pointer to description of the option.
190 * Needed to initialize an AbstractOptionStorage object from this class
191 * without otherwise unnecessary accessors.
193 friend class AbstractOptionStorage;
195 * Needed to be able to call createStorage().
197 friend class Options;
201 * Templated base class for constructing concrete option settings classes.
203 * \tparam T Assignable type that stores a single option value.
204 * \tparam U Type of the derived class.
206 * This template is used as a base class like this:
208 class ConcreteOption : public OptionTemplate<int, ConcreteOption>
212 * All public functions in this class return \c *this casted to a reference to
213 * \p U. They do not throw.
215 * For examples of how to use classes derived from this class, see the class
216 * documentation for Options.
219 * \ingroup module_options
221 template <typename T, class U>
222 class OptionTemplate : public AbstractOption
225 //! Type that stores a single option value.
227 //! Alias for the derived class type.
231 * Sets a description for the option.
233 * \param[in] descr Description to set.
235 * String in \p descr is copied when the option is created.
237 MyClass &description(const char *descr)
238 { setDescription(descr); return me(); }
239 //! Hides the option from normal help output.
240 MyClass &hidden(bool bHidden = true)
241 { setFlag(efOption_Hidden, bHidden); return me(); }
243 * Requires the option to be specified explicitly.
245 * Note that if you specify defaultValue() together with required(),
246 * the user is not required to explicitly provide the option.
247 * In this case, required() only affects possible help output.
249 MyClass &required(bool bRequired = true)
250 { setFlag(efOption_Required, bRequired); return me(); }
251 //! Allows the option to be specified multiple times.
252 MyClass &allowMultiple(bool bMulti = true)
253 { setFlag(efOption_MultipleTimes, bMulti); return me(); }
254 //! Requires exactly \p count values for the option.
255 MyClass &valueCount(int count) { setValueCount(count); return me(); }
256 //! Allows any number of values for the option.
257 MyClass &multiValue(bool bMulti = true)
258 { if (bMulti) { maxValueCount_ = -1; } return me(); }
261 * Sets a default value for the option.
263 * \param[in] defaultValue Default value.
265 * If the option is never set, the default value is copied to the
266 * assigned storage. Note that if the option is not set and there
267 * is no default value, the storage is not altered, which can also be
268 * used to provide a default value. The latter method has to be used
269 * if the option can take multiple values.
271 * \p defaultValue is copied when the option is created.
273 MyClass &defaultValue(const T &defaultValue)
274 { defaultValue_ = &defaultValue; return me(); }
276 * Sets a default value for the option when it is set.
278 * \param[in] defaultValue Default value.
280 * This value is used if the option is set, but no value is provided.
281 * If the option is never set, the value set with defaultValue() is
282 * used. Can only be used for options that accept a single value.
284 * \p defaultValue is copied when the option is created.
286 MyClass &defaultValueIfSet(const T &defaultValue)
287 { defaultValueIfSet_ = &defaultValue; return me(); }
289 * Stores value(s) in memory pointed by \p store.
291 * \param[in] store Storage for option value(s).
293 * The caller is responsible for allocating enough memory such that
294 * the any allowed number of values fits into the array pointed by
295 * \p store. If there is no maximum allowed number or if the maximum
296 * is inconveniently large, storeVector() should be used.
298 * For information on when values are available in the storage, see
301 * The pointer provided should remain valid as long as the associated
302 * Options object exists.
304 MyClass &store(T *store)
305 { store_ = store; return me(); }
307 * Stores number of values in the value pointed by \p countptr.
309 * \param[in] countptr Storage for the number of values.
311 * For information on when values are available in the storage, see
314 * The pointers provided should remain valid as long as the associated
315 * Options object exists.
317 MyClass &storeCount(int *countptr)
318 { countptr_ = countptr; return me(); }
320 * Stores option values in the provided vector.
322 * \param[in] store Vector to store option values in.
324 * Values are added to the vector after each successful set of values
325 * is parsed. Note that for some options, the value may be changed
326 * later, and is only guaranteed to be correct after Options::finish()
329 * The pointer provided should remain valid as long as the associated
330 * Options object exists.
332 MyClass &storeVector(std::vector<T> *store)
333 { storeVector_ = store; return me(); }
337 //! Alias for the template class for use in base classes.
338 typedef OptionTemplate<T, U> MyBase;
340 //! Initializes the name and default values for an option.
341 explicit OptionTemplate(const char *name)
342 : AbstractOption(name),
343 defaultValue_(NULL), defaultValueIfSet_(NULL), store_(NULL),
344 countptr_(NULL), storeVector_(NULL)
348 * Returns a pointer to user-specified default value, or NULL if there
351 const T *defaultValue() const { return defaultValue_; }
353 * Returns a pointer to user-specified default value, or NULL if there
356 const T *defaultValueIfSet() const { return defaultValueIfSet_; }
357 //! Returns \p *this casted into MyClass to reduce typing.
358 MyClass &me() { return static_cast<MyClass &>(*this); }
362 const T *defaultValue_;
363 const T *defaultValueIfSet_;
366 std::vector<T> *storeVector_;
369 * Needed to initialize storage from this class without otherwise
370 * unnecessary accessors.
372 friend class OptionStorageTemplate<T>;
376 * Gives information and allows modifications to an option after creation.
378 * When an option is added with Options::addOption(), an object of a subclass
379 * of OptionInfo is returned. This object can be later used to access
380 * information about the option. Non-const methods also allow later changing
381 * (some of) the option settings provided at initialization time.
382 * The properties accessible/modifiable through this interface are implemented
383 * based on need, and may not be implemented for all cases.
386 * This class is also used by OptionsVisitor and OptionsModifyingVisitor as
387 * the interface that allows querying/modifying each visited option.
390 * This class isolates the details of the internal option implementation from
391 * callers. Although this class is a simple reference to the underlying
392 * implementation, it is implemented as non-copyable to allow const/non-const
393 * status of a reference to this class to indicate whether modifications are
394 * allowed. Otherwise, separate classes would be needed for access and
395 * modification, complicating the implementation. In the implementation,
396 * there is always a single OptionInfo instance referring to one option.
397 * The underlying implementation object always owns this instance, and only
398 * references are passed to callers.
400 * \see Options::addOption()
402 * \see OptionsVisitor
403 * \see OptionsModifyingVisitor
407 * \ingroup module_options
412 virtual ~OptionInfo();
415 * Test whether the option is of a particular type.
417 * \tparam InfoType Option type to test for. Should be a class derived
420 template <class InfoType>
423 return toType<InfoType>() != NULL;
426 * Convert the info object to a particular type if the type is correct.
428 * \tparam InfoType Option type to convert to. Should be a class
429 * derived from OptionInfo.
430 * \retval this converted to a pointer to \p InfoType, or NULL if the
431 * conversion is not possible.
433 template <class InfoType>
436 return dynamic_cast<InfoType *>(this);
438 //! \copydoc toType()
439 template <class InfoType>
440 const InfoType *toType() const
442 return dynamic_cast<const InfoType *>(this);
445 //! Returns true if the option has been set.
447 //! Returns true if the option is a hidden option.
448 bool isHidden() const;
449 //! Returns true if the option is required.
450 bool isRequired() const;
451 //! Returns the minimum number of values that this option accepts.
452 int minValueCount() const;
453 //! Returns the maximum number of values that this option accepts.
454 int maxValueCount() const;
455 //! Returns the name of the option.
456 const std::string &name() const;
457 //! Returns the type of the option as a string.
458 std::string type() const;
459 //! Returns the description of the option.
460 std::string formatDescription() const;
462 * Returns the default value if set for the option as a string.
464 * \see OptionTemplate::defaultValueIfSet()
466 std::string formatDefaultValueIfSet() const;
468 //! Returns the number of values given for the option.
469 int valueCount() const;
470 //! Returns the i'th value of the option as a string.
471 std::string formatValue(int i) const;
476 * Wraps a given option object.
480 explicit OptionInfo(AbstractOptionStorage *option);
482 //! Returns the wrapped option storage object.
483 AbstractOptionStorage &option() { return option_; }
484 //! Returns the wrapped option storage object.
485 const AbstractOptionStorage &option() const { return option_; }
489 //! The wrapped option.
490 AbstractOptionStorage &option_;
492 GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo);