Merge branch release-4-6
[alexxy/gromacs.git] / src / gromacs / options / options.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2012, by the GROMACS development team, led by
5  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
6  * others, as listed in the AUTHORS file in the top-level source
7  * directory and at http://www.gromacs.org.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \file
36  * \brief
37  * Declares gmx::Options.
38  *
39  * Together with basicoptions.h, this header forms the part of the public
40  * API that most classes will use to provide options.
41  *
42  * \author Teemu Murtola <teemu.murtola@gmail.com>
43  * \inpublicapi
44  * \ingroup module_options
45  */
46 #ifndef GMX_OPTIONS_OPTIONS_H
47 #define GMX_OPTIONS_OPTIONS_H
48
49 #include <string>
50
51 #include "../utility/common.h"
52 #include "../utility/gmxassert.h"
53
54 #include "abstractoption.h"
55
56 namespace gmx
57 {
58
59 class AbstractOption;
60 class OptionsAssigner;
61 class OptionsIterator;
62
63 /*! \brief
64  * Collection of options.
65  *
66  * This class provides a standard interface for implementing input options.
67  * Standard usage is to write a method that creates an Options that is owned by
68  * the object, populates it with supported options, and then returns it:
69  * \code
70    // <as class attributes>
71    using gmx::Options;
72    Options      options("common", "Common Options");
73    std::string  arg1;
74    int          arg2;
75
76    // <populating>
77    using gmx::StringOption;
78    using gmx::IntegerOption;
79    options.addOption(StringOption("arg1").store(&arg1));
80    options.addOption(IntegerOption("arg2").store(&arg2));
81    return &options;
82  * \endcode
83  * The caller of that method can then use a parser implementation such as
84  * CommandLineParser to provide values for the options.
85  *
86  * Header basicoptions.h provides declarations of several standard
87  * option types for use with addOption().  Documentation of those classes
88  * also give more examples of how to define options.
89  *
90  * In order to keep the public interface of this class simple and to reduce
91  * build dependencies on objects that simply provide options, functionality
92  * to assign values to options is provided by a separate OptionsAssigner class.
93  * Similarly, functionality for looping over all options (e.g., for writing out
94  * help) is provided by OptionsIterator.
95  *
96  * \inpublicapi
97  * \ingroup module_options
98  */
99 class Options
100 {
101     public:
102         /*! \brief
103          * Initializes the name and title of an option collection.
104          *
105          * \param[in] name  Single-word name.
106          * \param[in] title Descriptive title.
107          *
108          * Copies the input strings.
109          */
110         Options(const char *name, const char *title);
111         ~Options();
112
113         //! Returns the short name of the option collection.
114         const std::string &name() const;
115         //! Returns the title of the option collection.
116         const std::string &title() const;
117         //! Returns the full description of the option collection.
118         const std::string &description() const;
119
120         /*! \brief
121          * Sets the full description of the option collection.
122          *
123          * \param[in] desc  String to set as the description.
124          *
125          * concatenateStrings() is useful for forming the input string.
126          */
127         void setDescription(const std::string &desc);
128         //int addBugs(int nbugs, const char *const *bugs);
129
130         /*! \brief
131          * Adds an option collection as a subsection of this collection.
132          *
133          * \param[in] section Subsection to add.
134          *
135          * The name() field of \p section is used as the name of the
136          * subsection.  If an attempt is made to add two different subsections
137          * with the same name, this function asserts.
138          *
139          * For certain functionality to work properly, no options should
140          * be added to the subsection after it has been added to another
141          * collection.
142          *
143          * Only a pointer to the provided object is stored.  The caller is
144          * responsible that the object exists for the lifetime of the
145          * collection.
146          * It is not possible to add the same Options object as a subsection to
147          * several different Options.
148          * If an attempt is made, the function asserts.
149          */
150         void addSubSection(Options *section);
151         /*! \brief
152          * Adds a recognized option to the collection.
153          *
154          * \param[in] settings Option description.
155          * \returns   OptionInfo object for the created option (never NULL).
156          * \throws    APIError if invalid option settings are provided.
157          *
158          * This method provides the internal implementation, but in most cases
159          * the templated method is called from user code.
160          * See the templated method for more details.
161          */
162         OptionInfo *addOption(const AbstractOption &settings);
163         /*! \brief
164          * Adds a recognized option to the collection.
165          *
166          * \tparam    OptionType Type of the options description object.
167          * \param[in] settings   Option description.
168          * \returns   OptionInfo object for the created option (never NULL).
169          * \throws    APIError if invalid option settings are provided.
170          *
171          * The return value is a pointer for more convenient use in callers:
172          * often callers need to declare the variable that will hold the return
173          * value in wider scope than would be achieved by declaring it at the
174          * site where addOption() is called.
175          * The returned pointer must not be freed.
176          *
177          * See \link Options class documentation \endlink for example usage.
178          *
179          * \libinternal
180          * \p OptionType::InfoType must specify a type that derives from
181          * OptionInfo and matches the type that is returned by
182          * AbstractOptionStorage::optionInfo() for the storage object that
183          * corresponds to \p OptionType.
184          */
185         template <class OptionType>
186         typename OptionType::InfoType *addOption(const OptionType &settings)
187         {
188             OptionInfo *info
189                 = addOption(static_cast<const AbstractOption &>(settings));
190             GMX_ASSERT(info->isType<typename OptionType::InfoType>(),
191                        "Mismatching option info type declaration and implementation");
192             return info->toType<typename OptionType::InfoType>();
193         }
194
195         //! Returns true if option \p name is set.
196         bool isSet(const char *name) const;
197         /*! \brief
198          * Notifies the collection that all option values are assigned.
199          *
200          * \throws InvalidInputError if invalid user input is detected.
201          *
202          * This function should be called after no more option values are
203          * to be assigned.  Values in storage variables are guaranteed to be
204          * available only after this call, although in most cases, they are
205          * available already during assignment.
206          *
207          * If invalid option values, e.g., missing required option, is detected
208          * at this point, this function throws.  The thrown exception contains
209          * information on all errors detected during the call.
210          */
211         void finish();
212
213     private:
214         class Impl;
215
216         PrivateImplPointer<Impl> impl_;
217
218         //! Needed to be able to extend the interface of this object.
219         friend class OptionsAssigner;
220         //! Needed to be able to extend the interface of this object.
221         friend class OptionsIterator;
222         //! Needed to be able to extend the interface of this object.
223         friend class OptionsModifyingIterator;
224 };
225
226 } // namespace gmx
227
228 #endif