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