Remove PrivateImplPointer in favour of std::unique_ptr
[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,2014,2016 by the GROMACS development team.
5  * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
6  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7  * and including many others, as listed in the AUTHORS file in the
8  * top-level source directory and at http://www.gromacs.org.
9  *
10  * GROMACS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1
13  * of the License, or (at your option) any later version.
14  *
15  * GROMACS is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with GROMACS; if not, see
22  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24  *
25  * If you want to redistribute modifications to GROMACS, please
26  * consider that scientific software is very special. Version
27  * control is crucial - bugs must be traceable. We will be happy to
28  * consider code for inclusion in the official distribution, but
29  * derived work must not be called official GROMACS. Details are found
30  * in the README & COPYING files - if they are missing, get the
31  * official version at http://www.gromacs.org.
32  *
33  * To help us fund GROMACS development, we humbly ask that you cite
34  * the research papers on the package. Check out http://www.gromacs.org.
35  */
36 /*! \libinternal \file
37  * \brief
38  * Declares gmx::OptionsVisitor interface and supporting classes.
39  *
40  * \author Teemu Murtola <teemu.murtola@gmail.com>
41  * \inlibraryapi
42  * \ingroup module_options
43  */
44 #ifndef GMX_OPTIONS_OPTIONSVISITOR_H
45 #define GMX_OPTIONS_OPTIONSVISITOR_H
46
47 #include <cstddef>
48
49 #include <memory>
50 #include <string>
51
52 #include "gromacs/options/abstractoption.h"
53 #include "gromacs/utility/classhelpers.h"
54
55 namespace gmx
56 {
57
58 class Options;
59 class OptionSectionInfo;
60
61 namespace internal
62 {
63 class OptionSectionImpl;
64 }
65
66 /*! \libinternal \brief
67  * Pure interface for visiting options in a Options object.
68  *
69  * \see OptionsIterator
70  *
71  * \inlibraryapi
72  * \ingroup module_options
73  */
74 class OptionsVisitor
75 {
76 public:
77     virtual ~OptionsVisitor() {}
78
79     //! Called for each section.
80     virtual void visitSection(const OptionSectionInfo& section) = 0;
81     //! Called for each option.
82     virtual void visitOption(const OptionInfo& option) = 0;
83 };
84
85 /*! \libinternal \brief
86  * Abstract base class for visiting options of a particular type.
87  *
88  * \see OptionsIterator
89  * \see OptionsVisitor
90  *
91  * \inlibraryapi
92  * \ingroup module_options
93  */
94 template<class InfoType>
95 class OptionsTypeVisitor : public OptionsVisitor
96 {
97 public:
98     ~OptionsTypeVisitor() override {}
99
100     void visitSection(const OptionSectionInfo& section) override = 0;
101     /*! \brief
102      * Called for each option of type \p InfoType.
103      */
104     virtual void visitOptionType(const InfoType& option) = 0;
105
106 private:
107     void visitOption(const OptionInfo& option) override
108     {
109         const InfoType* subtype = option.toType<InfoType>();
110         if (subtype != NULL)
111         {
112             visitOptionType(*subtype);
113         }
114     }
115 };
116
117 /*! \libinternal \brief
118  * Decorator class for visiting options in a Options object.
119  *
120  * This class provides an interface for looping through sections and
121  * options in a Options object.
122  *
123  * Typical use (loop over all options, iteratively descending into
124  * subsections):
125  * \code
126    class Visitor : public gmx::OptionsVisitor
127    {
128        public:
129            virtual void visitSection(const OptionSectionInfo &section)
130            {
131                OptionsIterator iterator(section);
132                iterator.acceptSections(this);
133                iterator.acceptOptions(this);
134            }
135
136            virtual void visitOption(const OptionInfo &option)
137            {
138                // Do something.
139            }
140    }
141
142    Visitor().visitSection(options.rootSection());
143  * \endcode
144  *
145  * \inlibraryapi
146  * \ingroup module_options
147  */
148 class OptionsIterator
149 {
150 public:
151     /*! \brief
152      * Creates an object for visiting options in a Options object.
153      *
154      * The created iterator iterates over the "root" section in the Options
155      * object.
156      */
157     explicit OptionsIterator(const Options& options);
158     //! Creates an object for visiting options in an options section.
159     explicit OptionsIterator(const OptionSectionInfo& section);
160
161     //! Visits each section in the wrapped section.
162     void acceptSections(OptionsVisitor* visitor) const;
163     //! Visits each option in the wrapped section.
164     void acceptOptions(OptionsVisitor* visitor) const;
165
166 private:
167     //! The wrapped section object.
168     const internal::OptionSectionImpl& section_;
169
170     GMX_DISALLOW_COPY_AND_ASSIGN(OptionsIterator);
171 };
172
173 /*! \libinternal \brief
174  * Pure interface for visiting options in a Options object, allowing
175  * modifications.
176  *
177  * \see OptionsModifyingIterator
178  *
179  * \inlibraryapi
180  * \ingroup module_options
181  */
182 class OptionsModifyingVisitor
183 {
184 public:
185     virtual ~OptionsModifyingVisitor() {}
186
187     //! Called for each section.
188     virtual void visitSection(OptionSectionInfo* section) = 0;
189     //! Called for each option.
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     ~OptionsModifyingTypeVisitor() override {}
208
209     void visitSection(OptionSectionInfo* section) override = 0;
210     /*! \brief
211      * Called for each option of type \p InfoType.
212      */
213     virtual void visitOptionType(InfoType* option) = 0;
214
215 private:
216     void visitOption(OptionInfo* option) override
217     {
218         InfoType* subtype = option->toType<InfoType>();
219         if (subtype != nullptr)
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      * The created iterator iterates over the "root" section in the Options
244      * object.
245      */
246     explicit OptionsModifyingIterator(Options* options);
247     //! Creates an object for visiting options in an options section.
248     explicit OptionsModifyingIterator(OptionSectionInfo* section);
249
250     //! Visits each section in the wrapped section.
251     void acceptSections(OptionsModifyingVisitor* visitor) const;
252     //! Visits each option in the wrapped section.
253     void acceptOptions(OptionsModifyingVisitor* visitor) const;
254
255 private:
256     //! The wrapped section object.
257     internal::OptionSectionImpl& section_;
258
259     GMX_DISALLOW_COPY_AND_ASSIGN(OptionsModifyingIterator);
260 };
261
262 } // namespace gmx
263
264 #endif