862b28ee57c2eaa32c92beb27892e866eb0f831e
[alexxy/gromacs.git] / src / gromacs / options / optionsvisitor.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  * 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.
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 /*! \libinternal \file
36  * \brief
37  * Declares gmx::OptionsVisitor interface and supporting classes.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inlibraryapi
41  * \ingroup module_options
42  */
43 #ifndef GMX_OPTIONS_OPTIONSVISITOR_H
44 #define GMX_OPTIONS_OPTIONSVISITOR_H
45
46 #include <cstddef>
47
48 #include <string>
49
50 #include "../utility/common.h"
51
52 #include "abstractoption.h"
53
54 namespace gmx
55 {
56
57 class Options;
58
59 /*! \libinternal \brief
60  * Pure interface for visiting options in a Options object.
61  *
62  * \see OptionsIterator
63  *
64  * \inlibraryapi
65  * \ingroup module_options
66  */
67 class OptionsVisitor
68 {
69     public:
70         virtual ~OptionsVisitor() {}
71
72         /*! \brief
73          * Called for each subsection in Options.
74          */
75         virtual void visitSubSection(const Options &section) = 0;
76         /*! \brief
77          * Called for each option in Options.
78          */
79         virtual void visitOption(const OptionInfo &option) = 0;
80 };
81
82 /*! \libinternal \brief
83  * Abstract base class for visiting options of a particular type.
84  *
85  * \see OptionsIterator
86  * \see OptionsVisitor
87  *
88  * \inlibraryapi
89  * \ingroup module_options
90  */
91 template <class InfoType>
92 class OptionsTypeVisitor : public OptionsVisitor
93 {
94     public:
95         virtual ~OptionsTypeVisitor() {}
96
97         virtual void visitSubSection(const Options &section) = 0;
98         /*! \brief
99          * Called for each option of type \p InfoType.
100          */
101         virtual void visitOptionType(const InfoType &option) = 0;
102
103     private:
104         virtual void visitOption(const OptionInfo &option)
105         {
106             const InfoType *subtype = option.toType<InfoType>();
107             if (subtype != NULL)
108             {
109                 visitOptionType(*subtype);
110             }
111         }
112 };
113
114 /*! \libinternal \brief
115  * Decorator class for visiting options in a Options object.
116  *
117  * This class provides an interface for looping through subsections and
118  * options in a Options object.
119  *
120  * Typical use (loop over all options, iteratively descending into
121  * subsections):
122  * \code
123    class Visitor : public gmx::OptionsVisitor
124    {
125        public:
126            void visitSubSection(const Options &section)
127            {
128                OptionsIterator iterator(section);
129                iterator.acceptSubSections(this);
130                iterator.acceptOptions(this);
131            }
132
133            void visitOption(const OptionInfo &option)
134            {
135                // Do something.
136            }
137    }
138
139    Visitor().visitSubSection(options);
140  * \endcode
141  *
142  * \inlibraryapi
143  * \ingroup module_options
144  */
145 class OptionsIterator
146 {
147     public:
148         /*! \brief
149          * Creates an object for visiting options in a Options object.
150          */
151         explicit OptionsIterator(const Options &options);
152
153         /*! \brief
154          * Visits each subsection in the wrapped Options object.
155          */
156         void acceptSubSections(OptionsVisitor *visitor) const;
157         /*! \brief
158          * Visits each option in the wrapped Options object.
159          */
160         void acceptOptions(OptionsVisitor *visitor) const;
161
162     private:
163         //! The wrapped Options object.
164         const Options          &options_;
165
166         GMX_DISALLOW_COPY_AND_ASSIGN(OptionsIterator);
167 };
168
169 /*! \libinternal \brief
170  * Pure interface for visiting options in a Options object, allowing
171  * modifications.
172  *
173  * \see OptionsModifyingIterator
174  *
175  * \inlibraryapi
176  * \ingroup module_options
177  */
178 class OptionsModifyingVisitor
179 {
180     public:
181         virtual ~OptionsModifyingVisitor() {}
182
183         /*! \brief
184          * Called for each subsection in Options.
185          */
186         virtual void visitSubSection(Options *section) = 0;
187         /*! \brief
188          * Called for each option in Options.
189          */
190         virtual void visitOption(OptionInfo *option) = 0;
191 };
192
193 /*! \libinternal \brief
194  * Abstract base class for visiting options of a particular type, allowing
195  * modifications.
196  *
197  * \see OptionsModifyingIterator
198  * \see OptionsModifyingVisitor
199  *
200  * \inlibraryapi
201  * \ingroup module_options
202  */
203 template <class InfoType>
204 class OptionsModifyingTypeVisitor : public OptionsModifyingVisitor
205 {
206     public:
207         virtual ~OptionsModifyingTypeVisitor() {}
208
209         virtual void visitSubSection(Options *section) = 0;
210         /*! \brief
211          * Called for each option of type \p InfoType.
212          */
213         virtual void visitOptionType(InfoType *option) = 0;
214
215     private:
216         virtual void visitOption(OptionInfo *option)
217         {
218             InfoType *subtype = option->toType<InfoType>();
219             if (subtype != NULL)
220             {
221                 visitOptionType(subtype);
222             }
223         }
224 };
225
226 /*! \libinternal \brief
227  * Decorator class for visiting options in a Options object, allowing changes.
228  *
229  * This class works exactly like OptionsIterator, except that it uses
230  * OptionsModifyingVisitor interface, which allows modifying the options.
231  *
232  * \see OptionsIterator
233  *
234  * \inlibraryapi
235  * \ingroup module_options
236  */
237 class OptionsModifyingIterator
238 {
239     public:
240         /*! \brief
241          * Creates an object for visiting options in a Options object.
242          */
243         explicit OptionsModifyingIterator(Options *options);
244
245         /*! \brief
246          * Visits each subsection in the wrapped Options object.
247          */
248         void acceptSubSections(OptionsModifyingVisitor *visitor) const;
249         /*! \brief
250          * Visits each option in the wrapped Options object.
251          */
252         void acceptOptions(OptionsModifyingVisitor *visitor) const;
253
254     private:
255         //! The wrapped Options object.
256         Options                &options_;
257
258         GMX_DISALLOW_COPY_AND_ASSIGN(OptionsModifyingIterator);
259 };
260
261 } // namespace gmx
262
263 #endif