Only accept exact matches for selection keywords
[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, 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     : public std::iterator<std::input_iterator_tag, const SelectionParserSymbol>
146 {
147     public:
148         //! Creates an independent copy of an iterator.
149         SelectionParserSymbolIterator(const SelectionParserSymbolIterator &other);
150         ~SelectionParserSymbolIterator();
151
152         //! Creates an independent copy of an iterator.
153         SelectionParserSymbolIterator &
154         operator=(const SelectionParserSymbolIterator &other);
155
156         //! Equality comparison for iterators.
157         bool operator==(const SelectionParserSymbolIterator &other) const;
158         //! Inequality comparison for iterators.
159         bool operator!=(const SelectionParserSymbolIterator &other) const
160         {
161             return !operator==(other);
162         }
163         //! Dereferences the iterator.
164         reference operator*() const;
165         //! Dereferences the iterator.
166         pointer operator->() const { return &operator*(); }
167         //! Moves the iterator to the next symbol.
168         SelectionParserSymbolIterator &operator++();
169         //! Moves the iterator to the next symbol.
170         SelectionParserSymbolIterator operator++(int)
171         {
172             SelectionParserSymbolIterator tmp(*this);
173             operator++();
174             return tmp;
175         }
176
177     private:
178         class Impl;
179
180         /*! \brief
181          * Initializes a new iterator with the given data.
182          *
183          * \param  impl  Implementation data.
184          *
185          * Only the parent symbol table can create non-default-constructed
186          * iterators.
187          */
188         explicit SelectionParserSymbolIterator(Impl *impl);
189
190         PrivateImplPointer<Impl> impl_;
191
192         /*! \brief
193          * Needed to access the constructor.
194          */
195         friend class SelectionParserSymbolTable;
196 };
197
198 /*! \internal \brief
199  * Symbol table for the selection parser.
200  *
201  * \ingroup module_selection
202  */
203 class SelectionParserSymbolTable
204 {
205     public:
206         /*! \brief
207          * Creates a new symbol table.
208          *
209          * \throws std::bad_alloc if out of memory.
210          *
211          * The created table is initialized with reserved and position symbols.
212          */
213         SelectionParserSymbolTable();
214         ~SelectionParserSymbolTable();
215
216         /*! \brief
217          * Finds a symbol by name.
218          *
219          * \param[in] name   Symbol name to find.
220          * \returns   Pointer to the symbol with name \p name, or
221          *      NULL if not found.
222          *
223          * Does not throw.
224          */
225         const SelectionParserSymbol *
226         findSymbol(const std::string &name) const;
227
228         /*! \brief
229          * Returns the start iterator for iterating symbols of a given type.
230          *
231          * \param[in] type  Type of symbols to iterate over.
232          * \returns   Iterator that points to the first symbol of type \p type.
233          * \throws    std::bad_alloc if out of memory.
234          *
235          * \see SelectionParserSymbolIterator
236          */
237         SelectionParserSymbolIterator
238         beginIterator(SelectionParserSymbol::SymbolType type) const;
239         /*! \brief
240          * Returns the end iterator for symbol iteration.
241          *
242          * \throws    std::bad_alloc if out of memory.
243          *
244          * Currently, the end value is the same for all symbol types.
245          *
246          * \see SelectionParserSymbolIterator
247          */
248         SelectionParserSymbolIterator endIterator() const;
249
250         /*! \brief
251          * Adds a new variable symbol.
252          *
253          * \param[in] name   Name of the new symbol.
254          * \param[in] sel    Value of the variable.
255          * \throws    std::bad_alloc if out of memory.
256          * \throws    InvalidInputError if there was a symbol with the same
257          *      name.
258          */
259         void addVariable(const char                        *name,
260                          const SelectionTreeElementPointer &sel);
261         /*! \brief
262          * Adds a new method symbol.
263          *
264          * \param[in] name   Name of the new symbol.
265          * \param[in] method Method that this symbol represents.
266          * \throws    std::bad_alloc if out of memory.
267          * \throws    APIError if there was a symbol with the same name.
268          */
269         void addMethod(const char *name, gmx_ana_selmethod_t *method);
270
271     private:
272         class Impl;
273
274         PrivateImplPointer<Impl> impl_;
275
276         /*! \brief
277          * Needed to access implementation types.
278          */
279         friend class SelectionParserSymbolIterator;
280 };
281
282 } // namespace gmx
283
284 #endif