Apply clang-format to source tree
[alexxy/gromacs.git] / src / gromacs / selection / symrec.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2019, 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 /*! \internal \file
36  * \brief Handling of selection parser symbol table.
37  *
38  * This is an implementation header: there should be no need to use it outside
39  * this directory.
40  *
41  * \author Teemu Murtola <teemu.murtola@gmail.com>
42  * \ingroup module_selection
43  */
44 #ifndef GMX_SELECTION_SYMREC_H
45 #define GMX_SELECTION_SYMREC_H
46
47 #include <iterator>
48 #include <string>
49
50 #include "gromacs/utility/classhelpers.h"
51
52 #include "selelem.h"
53
54 struct gmx_ana_selmethod_t;
55
56 namespace gmx
57 {
58
59 class SelectionParserSymbolTable;
60
61 /*! \internal
62  * \brief
63  * Single symbol for the selection parser.
64  *
65  * Public methods in this class do not throw.
66  *
67  * \ingroup module_selection
68  */
69 class SelectionParserSymbol
70 {
71 public:
72     //! Defines the type of the symbol.
73     enum SymbolType
74     {
75         ReservedSymbol, //!< The symbol is a reserved keyword.
76         VariableSymbol, //!< The symbol is a variable.
77         MethodSymbol,   //!< The symbol is a selection method.
78         PositionSymbol  //!< The symbol is a position keyword.
79     };
80
81     ~SelectionParserSymbol();
82
83     //! Returns the name of the symbol.
84     const std::string& name() const;
85     //! Returns the type of the symbol.
86     SymbolType type() const;
87
88     /*! \brief
89      * Returns the method associated with a \ref MethodSymbol symbol.
90      *
91      * \returns   The method associated with the symbol.
92      *
93      * Must only be called if type() returns \ref MethodSymbol.
94      */
95     gmx_ana_selmethod_t* methodValue() const;
96     /*! \brief
97      * Returns the selection tree associated with a \ref VariableSymbol symbol.
98      *
99      * \returns   The variable expression associated with the symbol.
100      *
101      * Must only be called if type() returns \ref VariableSymbol.
102      */
103     const SelectionTreeElementPointer& variableValue() const;
104
105 private:
106     class Impl;
107
108     /*! \brief
109      * Initializes a new symbol with the given data.
110      *
111      * \param  impl  Implementation data.
112      * \throws std::bad_alloc if out of memory.
113      *
114      * Only the parent symbol table creates symbol objects.
115      */
116     explicit SelectionParserSymbol(Impl* impl);
117
118     PrivateImplPointer<Impl> impl_;
119
120     /*! \brief
121      * Needed to call the constructor and for other initialization.
122      */
123     friend class SelectionParserSymbolTable;
124 };
125
126 /*! \internal
127  * \brief
128  * Input iterator for iterating symbols of a given type.
129  *
130  * Behaves as standard C++ input iterator.  To get an iterator, call
131  * SelectionParserSymbolTable::beginIterator().  Each time the iterator is
132  * incremented, it moves to the next symbol of the type given when the iterator
133  * was created.  When there are no more symbols, the iterator will equal
134  * SelectionParserSymbolTable::endIterator().  It is not allowed to dereference
135  * or increment an iterator that has reached the end.
136  *
137  * Construction and assignment may throw std::bad_alloc if out of memory.
138  * Other methods do not throw.
139  *
140  * \see SelectionParserSymbolTable::beginIterator()
141  *
142  * \ingroup module_selection
143  */
144 class SelectionParserSymbolIterator
145 {
146 public:
147     /*! \name Iterator type traits
148      * Satisfies the requirements for STL input iterator.
149      * \{
150      */
151     using iterator_category = std::input_iterator_tag;
152     using value_type        = const SelectionParserSymbol;
153     using difference_type   = std::ptrdiff_t;
154     using pointer           = const SelectionParserSymbol*;
155     using reference         = const SelectionParserSymbol&;
156     //! \}
157
158     //! Creates an independent copy of an iterator.
159     SelectionParserSymbolIterator(const SelectionParserSymbolIterator& other);
160     ~SelectionParserSymbolIterator();
161
162     //! Creates an independent copy of an iterator.
163     SelectionParserSymbolIterator& operator=(const SelectionParserSymbolIterator& other);
164
165     //! Equality comparison for iterators.
166     bool operator==(const SelectionParserSymbolIterator& other) const;
167     //! Inequality comparison for iterators.
168     bool operator!=(const SelectionParserSymbolIterator& other) const { return !operator==(other); }
169     //! Dereferences the iterator.
170     reference operator*() const;
171     //! Dereferences the iterator.
172     pointer operator->() const { return &operator*(); }
173     //! Moves the iterator to the next symbol.
174     SelectionParserSymbolIterator& operator++();
175     //! Moves the iterator to the next symbol.
176     SelectionParserSymbolIterator operator++(int)
177     {
178         SelectionParserSymbolIterator tmp(*this);
179                                       operator++();
180         return tmp;
181     }
182
183 private:
184     class Impl;
185
186     /*! \brief
187      * Initializes a new iterator with the given data.
188      *
189      * \param  impl  Implementation data.
190      *
191      * Only the parent symbol table can create non-default-constructed
192      * iterators.
193      */
194     explicit SelectionParserSymbolIterator(Impl* impl);
195
196     PrivateImplPointer<Impl> impl_;
197
198     /*! \brief
199      * Needed to access the constructor.
200      */
201     friend class SelectionParserSymbolTable;
202 };
203
204 /*! \internal \brief
205  * Symbol table for the selection parser.
206  *
207  * \ingroup module_selection
208  */
209 class SelectionParserSymbolTable
210 {
211 public:
212     /*! \brief
213      * Creates a new symbol table.
214      *
215      * \throws std::bad_alloc if out of memory.
216      *
217      * The created table is initialized with reserved and position symbols.
218      */
219     SelectionParserSymbolTable();
220     ~SelectionParserSymbolTable();
221
222     /*! \brief
223      * Finds a symbol by name.
224      *
225      * \param[in] name   Symbol name to find.
226      * \returns   Pointer to the symbol with name \p name, or
227      *      NULL if not found.
228      *
229      * Does not throw.
230      */
231     const SelectionParserSymbol* findSymbol(const std::string& name) const;
232
233     /*! \brief
234      * Returns the start iterator for iterating symbols of a given type.
235      *
236      * \param[in] type  Type of symbols to iterate over.
237      * \returns   Iterator that points to the first symbol of type \p type.
238      * \throws    std::bad_alloc if out of memory.
239      *
240      * \see SelectionParserSymbolIterator
241      */
242     SelectionParserSymbolIterator beginIterator(SelectionParserSymbol::SymbolType type) const;
243     /*! \brief
244      * Returns the end iterator for symbol iteration.
245      *
246      * \throws    std::bad_alloc if out of memory.
247      *
248      * Currently, the end value is the same for all symbol types.
249      *
250      * \see SelectionParserSymbolIterator
251      */
252     SelectionParserSymbolIterator endIterator() const;
253
254     /*! \brief
255      * Adds a new variable symbol.
256      *
257      * \param[in] name   Name of the new symbol.
258      * \param[in] sel    Value of the variable.
259      * \throws    std::bad_alloc if out of memory.
260      * \throws    InvalidInputError if there was a symbol with the same
261      *      name.
262      */
263     void addVariable(const char* name, const SelectionTreeElementPointer& sel);
264     /*! \brief
265      * Adds a new method symbol.
266      *
267      * \param[in] name   Name of the new symbol.
268      * \param[in] method Method that this symbol represents.
269      * \throws    std::bad_alloc if out of memory.
270      * \throws    APIError if there was a symbol with the same name.
271      */
272     void addMethod(const char* name, gmx_ana_selmethod_t* method);
273
274 private:
275     class Impl;
276
277     PrivateImplPointer<Impl> impl_;
278
279     /*! \brief
280      * Needed to access implementation types.
281      */
282     friend class SelectionParserSymbolIterator;
283 };
284
285 } // namespace gmx
286
287 #endif