Merge "Fix SelectionParserParameter move constructor problem."
[alexxy/gromacs.git] / src / gromacs / options / abstractoption.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
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.
13
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.
18  *
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.
25  *
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.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \file
32  * \brief
33  * Defines gmx::AbstractOption and a related template.
34  *
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.
38  *
39  * These classes also take care of creating and setting up the actual option
40  * objects.
41  *
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
44  * its subclasses.
45  *
46  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
47  * \inlibraryapi
48  * \ingroup module_options
49  */
50 #ifndef GMX_OPTIONS_ABSTRACTOPTION_H
51 #define GMX_OPTIONS_ABSTRACTOPTION_H
52
53 #include <string>
54 #include <vector>
55
56 #include "../utility/uniqueptr.h"
57
58 #include "optionflags.h"
59
60 namespace gmx
61 {
62
63 class AbstractOptionStorage;
64 template <typename T> class OptionStorageTemplate;
65 class Options;
66
67 //! Smart pointer for managing an AbstractOptionStorage object.
68 typedef gmx_unique_ptr<AbstractOptionStorage>::type
69         AbstractOptionStoragePointer;
70
71 /*! \brief
72  * Abstract base class for specifying option properties.
73  *
74  * Concrete classes should normally not derive directly from this class,
75  * but from OptionTemplate instead.  Classes derived from this class
76  * are mainly designed to implement the "named parameter" idiom.  For
77  * efficiency and clarity, these classes should only store values provided to
78  * them.  All error checking and memory management should be postponed to the
79  * point when the actual option is created.
80  *
81  * Subclasses should override createStorage() to create the correct type
82  * of storage object.  If they use their own info type derived from OptionInfo,
83  * they should also have a public typedef \c InfoType that specifies that
84  * info type.  This is required for Options::addOption() to return the correct
85  * info type.
86  *
87  * \ingroup module_options
88  */
89 class AbstractOption
90 {
91     public:
92         // Virtual only for completeness, in normal use should not be needed.
93         virtual ~AbstractOption() { }
94
95     protected:
96         /*! \cond libapi */
97         //! Initializes the name and default values for an option.
98         explicit AbstractOption(const char *name)
99             : minValueCount_(1), maxValueCount_(1),
100               name_(name), descr_(NULL)
101         { }
102
103         /*! \brief
104          * Creates a default storage object for the option.
105          *
106          * \returns The created storage object.
107          * \throws  APIError if invalid option settings have been provided.
108          *
109          * This method is called by Options::addOption() when initializing an
110          * option from the settings.
111          *
112          * Derived classes should implement the method to create an actual
113          * storage object and populate it with correct values.
114          * They should also throw APIError if they detect problems.
115          *
116          * Should only be called by Options::addOption().
117          */
118         virtual AbstractOptionStoragePointer createStorage() const = 0;
119
120         /*! \brief
121          * Creates the description string for the option.
122          *
123          * \returns Description string for the option.
124          *
125          * This function is virtual to allow derived classes to customize the
126          * description programmatically, e.g., by adding the list of allowed
127          * values.
128          * The default implementation simply returns the user-provided
129          * description.
130          */
131         virtual std::string createDescription() const
132         { return descr_ ? descr_ : ""; }
133
134         //! Sets the description for the option.
135         void setDescription(const char *descr) { descr_ = descr; }
136         //! Sets a flag for the option.
137         void setFlag(OptionFlag flag) { flags_.set(flag); }
138         //! Clears a flag for the option.
139         void clearFlag(OptionFlag flag) { flags_.clear(flag); }
140         //! Sets or clears a flag for the option.
141         void setFlag(OptionFlag flag, bool bSet) { flags_.set(flag, bSet); }
142         //! Returns true if the option is vector-valued.
143         bool isVector() const { return hasFlag(efOption_Vector); }
144         /*! \brief
145          * Sets the option to be vector-valued.
146          *
147          * This method is provided for convenience to make management of value
148          * counts easier.  In order to implement a vector-valued option, the
149          * class derived from AbstractOption should expose a method that calls
150          * this method, and the storage object derived from
151          * AbstractOptionStorage should check isVector().
152          * If only a single value is provided, the storage object should fill
153          * the whole vector with that value.
154          *
155          * The length of the vector (the value of maxValueCount_) must be
156          * fixed.  The default length is 3 elements.
157          */
158         void setVector()
159         {
160             setFlag(efOption_Vector);
161             minValueCount_ = 1;
162             if (maxValueCount_ == 1)
163             {
164                 maxValueCount_ = 3;
165             }
166         }
167         //! Sets the required number of values for the option.
168         void setValueCount(int count)
169         {
170             if (!hasFlag(efOption_Vector))
171             {
172                 minValueCount_ = count;
173             }
174             maxValueCount_ = count;
175         }
176
177         //! Minimum number of values required for the option.
178         int                     minValueCount_;
179         //! Maximum number of values allowed for the option.
180         int                     maxValueCount_;
181         //! \endcond
182
183     private:
184         //! Returns true if a flag has been set.
185         bool hasFlag(OptionFlag flag) const { return flags_.test(flag); }
186
187         const char             *name_;
188         //! Pointer to description of the option.
189         const char             *descr_;
190         OptionFlags             flags_;
191
192         /*! \brief
193          * Needed to initialize an AbstractOptionStorage object from this class
194          * without otherwise unnecessary accessors.
195          */
196         friend class AbstractOptionStorage;
197         /*! \brief
198          * Needed to be able to call createStorage().
199          */
200         friend class Options;
201 };
202
203 /*! \brief
204  * Templated base class for constructing concrete option settings classes.
205  *
206  * \tparam T Assignable type that stores a single option value.
207  * \tparam U Type of the derived class.
208  *
209  * This template is used as a base class like this:
210  * \code
211 class ConcreteOption : public OptionTemplate<int, ConcreteOption>
212 {
213  * \endcode
214  *
215  * All public functions in this class return \c *this casted to a reference to
216  * \p U.  They do not throw.
217  *
218  * For examples of how to use classes derived from this class, see the class
219  * documentation for Options.
220  *
221  * \inlibraryapi
222  * \ingroup module_options
223  */
224 template <typename T, class U>
225 class OptionTemplate : public AbstractOption
226 {
227     public:
228         //! Type that stores a single option value.
229         typedef T ValueType;
230         //! Alias for the derived class type.
231         typedef U MyClass;
232
233         /*! \brief
234          * Sets a description for the option.
235          *
236          * \param[in] descr Description to set.
237          *
238          * String in \p descr is copied when the option is created.
239          */
240         MyClass &description(const char *descr)
241         { setDescription(descr); return me(); }
242         //! Hides the option from normal help output.
243         MyClass &hidden(bool bHidden = true)
244         { setFlag(efOption_Hidden, bHidden); return me(); }
245         //! Requires the option to be specified explicitly.
246         MyClass &required(bool bRequired = true)
247         { setFlag(efOption_Required, bRequired); return me(); }
248         //! Allows the option to be specified multiple times.
249         MyClass &allowMultiple(bool bMulti = true)
250         { setFlag(efOption_MultipleTimes, bMulti); return me(); }
251         //! Requires exactly \p count values for the option.
252         MyClass &valueCount(int count) { setValueCount(count); return me(); }
253         //! Allows any number of values for the option.
254         MyClass &multiValue() { maxValueCount_ = -1; return me(); }
255
256         /*! \brief
257          * Sets a default value for the option.
258          *
259          * \param[in] defaultValue Default value.
260          *
261          * If the option is never set, the default value is copied to the
262          * assigned storage.  Note that if the option is not set and there
263          * is no default value, the storage is not altered, which can also be
264          * used to provide a default value.  The latter method has to be used
265          * if the option can take multiple values.
266          * If required() is specified, only affects the default value shown in
267          * help output.
268          *
269          * \p defaultValue is copied when the option is created.
270          */
271         MyClass &defaultValue(const T &defaultValue)
272         { defaultValue_ = &defaultValue; return me(); }
273         /*! \brief
274          * Sets a default value for the option when it is set.
275          *
276          * \param[in] defaultValue Default value.
277          *
278          * This value is used if the option is set, but no value is provided.
279          * If the option is never set, the value set with defaultValue() is
280          * used.  Can only be used for options that accept a single value.
281          *
282          * \p defaultValue is copied when the option is created.
283          */
284         MyClass &defaultValueIfSet(const T &defaultValue)
285         { defaultValueIfSet_ = &defaultValue; return me(); }
286         /*! \brief
287          * Stores value(s) in memory pointed by \p store.
288          *
289          * \param[in] store  Storage for option value(s).
290          *
291          * The caller is responsible for allocating enough memory such that
292          * the any allowed number of values fits into the array pointed by
293          * \p store.  If there is no maximum allowed number or if the maximum
294          * is inconveniently large, storeVector() should be used.
295          *
296          * For information on when values are available in the storage, see
297          * storeVector().
298          *
299          * The pointer provided should remain valid as long as the associated
300          * Options object exists.
301          */
302         MyClass &store(T *store)
303         { store_ = store; return me(); }
304         /*! \brief
305          * Stores number of values in the value pointed by \p countptr.
306          *
307          * \param[in] countptr Storage for the number of values.
308          *
309          * For information on when values are available in the storage, see
310          * storeVector().
311          *
312          * The pointers provided should remain valid as long as the associated
313          * Options object exists.
314          */
315         MyClass &storeCount(int *countptr)
316         { countptr_ = countptr; return me(); }
317         /*! \brief
318          * Stores option values in the provided vector.
319          *
320          * \param[in] store  Vector to store option values in.
321          *
322          * Values are added to the vector after each successful set of values
323          * is parsed.  Note that for some options, the value may be changed
324          * later, and is only guaranteed to be correct after Options::finish()
325          * has been called.
326          *
327          * The pointer provided should remain valid as long as the associated
328          * Options object exists.
329          */
330         MyClass &storeVector(std::vector<T> *store)
331         { storeVector_ = store; return me(); }
332
333     protected:
334         /*! \cond libapi */
335         //! Alias for the template class for use in base classes.
336         typedef OptionTemplate<T, U> MyBase;
337
338         //! Initializes the name and default values for an option.
339         explicit OptionTemplate(const char *name)
340             : AbstractOption(name),
341               defaultValue_(NULL), defaultValueIfSet_(NULL), store_(NULL),
342               countptr_(NULL), storeVector_(NULL)
343         { }
344
345         /*! \brief
346          * Returns a pointer to user-specified default value, or NULL if there
347          * is none.
348          */
349         const T *defaultValue() const { return defaultValue_; }
350         /*! \brief
351          * Returns a pointer to user-specified default value, or NULL if there
352          * is none.
353          */
354         const T *defaultValueIfSet() const { return defaultValueIfSet_; }
355         //! Returns \p *this casted into MyClass to reduce typing.
356         MyClass &me() { return static_cast<MyClass &>(*this); }
357         //! \endcond
358
359     private:
360         const T                *defaultValue_;
361         const T                *defaultValueIfSet_;
362         T                      *store_;
363         int                    *countptr_;
364         std::vector<T>         *storeVector_;
365
366         /*! \brief
367          * Needed to initialize storage from this class without otherwise
368          * unnecessary accessors.
369          */
370         friend class OptionStorageTemplate<T>;
371 };
372
373 } // namespace gmx
374
375 #endif