ba54295d526b5703d5f96c72bf6387d391e586a4
[alexxy/gromacs.git] / src / gromacs / options / abstractsection.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2016, 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 /*! \file
36  * \brief
37  * Declares base classes for declaring option sections.
38  *
39  * This header defines base classes for option section settings that are used
40  * with IOptionsContainerWithSections::addSection().  These classes implement
41  * the "named parameter" idiom for specifying section properties.
42  *
43  * \author Teemu Murtola <teemu.murtola@gmail.com>
44  * \ingroup module_options
45  */
46 #ifndef GMX_OPTIONS_ABSTRACTSECTION_H
47 #define GMX_OPTIONS_ABSTRACTSECTION_H
48
49 #include "gromacs/options/ioptionscontainerwithsections.h"
50 #include "gromacs/options/isectionstorage.h"
51 #include "gromacs/utility/classhelpers.h"
52 #include "gromacs/utility/gmxassert.h"
53
54 namespace gmx
55 {
56
57 class IOptionSectionStorage;
58
59 namespace internal
60 {
61 class OptionSectionImpl;
62 }
63
64 /*! \brief
65  * Base class for specifying option section properties.
66  *
67  * \ingroup module_options
68  */
69 class AbstractOptionSection
70 {
71     protected:
72         //! \cond libapi
73         //! Initializes option properties with the given name.
74         explicit AbstractOptionSection(const char *name) : name_(name) {}
75
76         /*! \brief
77          * Creates a storage object corresponding to this section.
78          *
79          * Similar to AbstractOption::createStorage().
80          */
81         virtual IOptionSectionStorage *createStorage() const = 0;
82         //! \endcond
83
84     private:
85         const char *name_;
86
87         friend class internal::OptionSectionImpl;
88 };
89
90 /*! \brief
91  * Base class for handles to option sections.
92  *
93  * This class implements the common functionality for adding options and
94  * subsections to option sections.
95  *
96  * \ingroup module_options
97  */
98 class AbstractOptionSectionHandle : public IOptionsContainerWithSections
99 {
100     public:
101         // From IOptionsContainer
102         //! \copydoc IOptionsContainer::addGroup()
103         virtual IOptionsContainer &addGroup();
104
105     protected:
106         //! \cond libapi
107         /*! \brief
108          * Returns the storage for a particular type of section.
109          *
110          * This is intended for use in derived class constructors, where the
111          * handle needs access to the actual storage.  The handle should know
112          * the type of storage created for the section type it deals with, so
113          * the cast should always be successful.
114          */
115         template <typename StorageType>
116         static StorageType *getStorage(internal::OptionSectionImpl *section)
117         {
118             IOptionSectionStorage *storage = getStorage(section);
119             StorageType           *typedStorage
120                 = dynamic_cast<StorageType *>(storage);
121             GMX_ASSERT(typedStorage != nullptr, "Mismatching section storage type");
122             return typedStorage;
123         }
124
125         //! Wraps a given section storage object.
126         explicit AbstractOptionSectionHandle(internal::OptionSectionImpl *section)
127             : section_(section)
128         {
129         }
130         //! \endcond
131
132     private:
133         // From IOptionsContainerWithSections
134         virtual internal::OptionSectionImpl *
135         addSectionImpl(const AbstractOptionSection &section);
136         // From IOptionsContainer
137         virtual OptionInfo *addOptionImpl(const AbstractOption &settings);
138
139         /*! \brief
140          * Implementation helper for the template method.
141          *
142          * This allows encapsulating the implementation within the source file.
143          */
144         static IOptionSectionStorage *getStorage(internal::OptionSectionImpl *section);
145
146         internal::OptionSectionImpl *section_;
147 };
148
149 class AbstractOptionSectionInfo
150 {
151     public:
152         //! Wraps a given section storage object.
153         explicit AbstractOptionSectionInfo(internal::OptionSectionImpl *section)
154             : section_(*section)
155         {
156         }
157
158         //! Returns the name of the section.
159         const std::string &name() const;
160
161         //! Returns the wrapped section storage object.
162         internal::OptionSectionImpl       &section() { return section_; }
163         //! Returns the wrapped section storage object.
164         const internal::OptionSectionImpl &section() const { return section_; }
165
166     private:
167         internal::OptionSectionImpl &section_;
168
169         GMX_DISALLOW_COPY_AND_ASSIGN(AbstractOptionSectionInfo);
170 };
171
172 } // namespace gmx
173
174 #endif