3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
33 * Defines gmx::AbstractOption, gmx::OptionTemplate and gmx::OptionInfo.
35 * This header defines base classes for option settings that are used with
36 * Options::addOption(). These classes implement the "named parameter"
37 * idiom for specifying option properties.
39 * These classes also take care of creating and setting up the actual option
42 * This header is needed directly only when implementing new option types,
43 * but methods of OptionTemplate are visible even to the normal user through
46 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
48 * \ingroup module_options
50 #ifndef GMX_OPTIONS_ABSTRACTOPTION_H
51 #define GMX_OPTIONS_ABSTRACTOPTION_H
56 #include "../utility/common.h"
57 #include "../utility/uniqueptr.h"
59 #include "optionflags.h"
64 class AbstractOptionStorage;
65 template <typename T> class OptionStorageTemplate;
68 //! Smart pointer for managing an AbstractOptionStorage object.
69 typedef gmx_unique_ptr<AbstractOptionStorage>::type
70 AbstractOptionStoragePointer;
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 * \returns The created storage object.
108 * \throws APIError if invalid option settings have been provided.
110 * This method is called by Options::addOption() when initializing an
111 * option from the settings.
113 * Derived classes should implement the method to create an actual
114 * storage object and populate it with correct values.
115 * They should also throw APIError if they detect problems.
117 * Should only be called by Options::addOption().
119 virtual AbstractOptionStoragePointer createStorage() const = 0;
122 * Creates the description string for the option.
124 * \returns Description string for the option.
126 * This function is virtual to allow derived classes to customize the
127 * description programmatically, e.g., by adding the list of allowed
129 * The default implementation simply returns the user-provided
132 virtual std::string createDescription() const
133 { return descr_ ? descr_ : ""; }
135 //! Sets the description for the option.
136 void setDescription(const char *descr) { descr_ = descr; }
137 //! Sets a flag for the option.
138 void setFlag(OptionFlag flag) { flags_.set(flag); }
139 //! Clears a flag for the option.
140 void clearFlag(OptionFlag flag) { flags_.clear(flag); }
141 //! Sets or clears a flag for the option.
142 void setFlag(OptionFlag flag, bool bSet) { flags_.set(flag, bSet); }
143 //! Returns true if the option is vector-valued.
144 bool isVector() const { return hasFlag(efOption_Vector); }
146 * Sets the option to be vector-valued.
148 * This method is provided for convenience to make management of value
149 * counts easier. In order to implement a vector-valued option, the
150 * class derived from AbstractOption should expose a method that calls
151 * this method, and the storage object derived from
152 * AbstractOptionStorage should check isVector().
153 * If only a single value is provided, the storage object should fill
154 * the whole vector with that value.
156 * The length of the vector (the value of maxValueCount_) must be
157 * fixed. The default length is 3 elements.
161 setFlag(efOption_Vector);
163 if (maxValueCount_ == 1)
168 //! Sets the required number of values for the option.
169 void setValueCount(int count)
171 if (!hasFlag(efOption_Vector))
173 minValueCount_ = count;
175 maxValueCount_ = count;
178 //! Minimum number of values required for the option.
180 //! Maximum number of values allowed for the option.
185 //! Returns true if a flag has been set.
186 bool hasFlag(OptionFlag flag) const { return flags_.test(flag); }
189 //! Pointer to description of the option.
194 * Needed to initialize an AbstractOptionStorage object from this class
195 * without otherwise unnecessary accessors.
197 friend class AbstractOptionStorage;
199 * Needed to be able to call createStorage().
201 friend class Options;
205 * Templated base class for constructing concrete option settings classes.
207 * \tparam T Assignable type that stores a single option value.
208 * \tparam U Type of the derived class.
210 * This template is used as a base class like this:
212 class ConcreteOption : public OptionTemplate<int, ConcreteOption>
216 * All public functions in this class return \c *this casted to a reference to
217 * \p U. They do not throw.
219 * For examples of how to use classes derived from this class, see the class
220 * documentation for Options.
223 * \ingroup module_options
225 template <typename T, class U>
226 class OptionTemplate : public AbstractOption
229 //! Type that stores a single option value.
231 //! Alias for the derived class type.
235 * Sets a description for the option.
237 * \param[in] descr Description to set.
239 * String in \p descr is copied when the option is created.
241 MyClass &description(const char *descr)
242 { setDescription(descr); return me(); }
243 //! Hides the option from normal help output.
244 MyClass &hidden(bool bHidden = true)
245 { setFlag(efOption_Hidden, bHidden); return me(); }
247 * Requires the option to be specified explicitly.
249 * Note that if you specify defaultValue() together with required(),
250 * the user is not required to explicitly provide the option.
251 * In this case, required() only affects possible help output.
253 MyClass &required(bool bRequired = true)
254 { setFlag(efOption_Required, bRequired); return me(); }
255 //! Allows the option to be specified multiple times.
256 MyClass &allowMultiple(bool bMulti = true)
257 { setFlag(efOption_MultipleTimes, bMulti); return me(); }
258 //! Requires exactly \p count values for the option.
259 MyClass &valueCount(int count) { setValueCount(count); return me(); }
260 //! Allows any number of values for the option.
261 MyClass &multiValue() { maxValueCount_ = -1; return me(); }
264 * Sets a default value for the option.
266 * \param[in] defaultValue Default value.
268 * If the option is never set, the default value is copied to the
269 * assigned storage. Note that if the option is not set and there
270 * is no default value, the storage is not altered, which can also be
271 * used to provide a default value. The latter method has to be used
272 * if the option can take multiple values.
274 * \p defaultValue is copied when the option is created.
276 MyClass &defaultValue(const T &defaultValue)
277 { defaultValue_ = &defaultValue; return me(); }
279 * Sets a default value for the option when it is set.
281 * \param[in] defaultValue Default value.
283 * This value is used if the option is set, but no value is provided.
284 * If the option is never set, the value set with defaultValue() is
285 * used. Can only be used for options that accept a single value.
287 * \p defaultValue is copied when the option is created.
289 MyClass &defaultValueIfSet(const T &defaultValue)
290 { defaultValueIfSet_ = &defaultValue; return me(); }
292 * Stores value(s) in memory pointed by \p store.
294 * \param[in] store Storage for option value(s).
296 * The caller is responsible for allocating enough memory such that
297 * the any allowed number of values fits into the array pointed by
298 * \p store. If there is no maximum allowed number or if the maximum
299 * is inconveniently large, storeVector() should be used.
301 * For information on when values are available in the storage, see
304 * The pointer provided should remain valid as long as the associated
305 * Options object exists.
307 MyClass &store(T *store)
308 { store_ = store; return me(); }
310 * Stores number of values in the value pointed by \p countptr.
312 * \param[in] countptr Storage for the number of values.
314 * For information on when values are available in the storage, see
317 * The pointers provided should remain valid as long as the associated
318 * Options object exists.
320 MyClass &storeCount(int *countptr)
321 { countptr_ = countptr; return me(); }
323 * Stores option values in the provided vector.
325 * \param[in] store Vector to store option values in.
327 * Values are added to the vector after each successful set of values
328 * is parsed. Note that for some options, the value may be changed
329 * later, and is only guaranteed to be correct after Options::finish()
332 * The pointer provided should remain valid as long as the associated
333 * Options object exists.
335 MyClass &storeVector(std::vector<T> *store)
336 { storeVector_ = store; return me(); }
340 //! Alias for the template class for use in base classes.
341 typedef OptionTemplate<T, U> MyBase;
343 //! Initializes the name and default values for an option.
344 explicit OptionTemplate(const char *name)
345 : AbstractOption(name),
346 defaultValue_(NULL), defaultValueIfSet_(NULL), store_(NULL),
347 countptr_(NULL), storeVector_(NULL)
351 * Returns a pointer to user-specified default value, or NULL if there
354 const T *defaultValue() const { return defaultValue_; }
356 * Returns a pointer to user-specified default value, or NULL if there
359 const T *defaultValueIfSet() const { return defaultValueIfSet_; }
360 //! Returns \p *this casted into MyClass to reduce typing.
361 MyClass &me() { return static_cast<MyClass &>(*this); }
365 const T *defaultValue_;
366 const T *defaultValueIfSet_;
369 std::vector<T> *storeVector_;
372 * Needed to initialize storage from this class without otherwise
373 * unnecessary accessors.
375 friend class OptionStorageTemplate<T>;
379 * Gives information and allows modifications to an option after creation.
381 * When an option is added with Options::addOption(), an object of a subclass
382 * of OptionInfo is returned. This object can be later used to access
383 * information about the option. Non-const methods also allow later changing
384 * (some of) the option settings provided at initialization time.
385 * The properties accessible/modifiable through this interface are implemented
386 * based on need, and may not be implemented for all cases.
389 * This class is also used by OptionsVisitor and OptionsModifyingVisitor as
390 * the interface that allows querying/modifying each visited option.
393 * This class isolates the details of the internal option implementation from
394 * callers. Although this class is a simple reference to the underlying
395 * implementation, it is implemented as non-copyable to allow const/non-const
396 * status of a reference to this class to indicate whether modifications are
397 * allowed. Otherwise, separate classes would be needed for access and
398 * modification, complicating the implementation. In the implementation,
399 * there is always a single OptionInfo instance referring to one option.
400 * The underlying implementation object always owns this instance, and only
401 * references are passed to callers.
403 * \see Options::addOption()
405 * \see OptionsVisitor
406 * \see OptionsModifyingVisitor
410 * \ingroup module_options
415 virtual ~OptionInfo();
418 * Test whether the option is of a particular type.
420 * \tparam InfoType Option type to test for. Should be a class derived
423 template <class InfoType>
426 return toType<InfoType>() != NULL;
429 * Convert the info object to a particular type if the type is correct.
431 * \tparam InfoType Option type to convert to. Should be a class
432 * derived from OptionInfo.
433 * \retval this converted to a pointer to \p InfoType, or NULL if the
434 * conversion is not possible.
436 template <class InfoType>
439 return dynamic_cast<InfoType *>(this);
441 //! \copydoc toType()
442 template <class InfoType>
443 const InfoType *toType() const
445 return dynamic_cast<const InfoType *>(this);
448 //! Returns true if the option has been set.
450 //! Returns true if the option is a hidden option.
451 bool isHidden() const;
452 //! Returns true if the option is required.
453 bool isRequired() const;
454 //! Returns the name of the option.
455 const std::string &name() const;
456 //! Returns the description of the option.
457 const std::string &description() const;
458 //! Returns the type of the option as a string.
459 const char *type() const;
460 //! Returns the number of values given for the option.
461 int valueCount() const;
462 //! Returns the i'th value of the option as a string.
463 std::string formatValue(int i) const;
465 * Returns the default value if set for the option as a string.
467 * \see OptionTemplate::defaultValueIfSet()
469 std::string formatDefaultValueIfSet() const;
474 * Wraps a given option object.
478 explicit OptionInfo(AbstractOptionStorage *option);
480 //! Returns the wrapped option storage object.
481 AbstractOptionStorage &option() { return option_; }
482 //! Returns the wrapped option storage object.
483 const AbstractOptionStorage &option() const { return option_; }
487 //! The wrapped option.
488 AbstractOptionStorage &option_;
490 GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo);