Reformat existing LGPL copyright notices.
[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, 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/common.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          * \param[in] bExact If false, symbols that begin with \p name are also
221          *      considered.
222          * \returns   Pointer to the symbol with name \p name, or
223          *      NULL if not found.
224          * \throws    InvalidInputError if \p bExact is false and an ambiguous
225          *      symbol is provided.
226          *
227          * If no exact match is found and \p bExact is false, returns a symbol
228          * that begins with \p name if a unique matching symbol is found.
229          * Only selection methods are considered for this inexact match.
230          */
231         const SelectionParserSymbol *
232         findSymbol(const std::string &name, bool bExact) const;
233
234         /*! \brief
235          * Returns the start iterator for iterating symbols of a given type.
236          *
237          * \param[in] type  Type of symbols to iterate over.
238          * \returns   Iterator that points to the first symbol of type \p type.
239          * \throws    std::bad_alloc if out of memory.
240          *
241          * \see SelectionParserSymbolIterator
242          */
243         SelectionParserSymbolIterator
244         beginIterator(SelectionParserSymbol::SymbolType type) const;
245         /*! \brief
246          * Returns the end iterator for symbol iteration.
247          *
248          * \throws    std::bad_alloc if out of memory.
249          *
250          * Currently, the end value is the same for all symbol types.
251          *
252          * \see SelectionParserSymbolIterator
253          */
254         SelectionParserSymbolIterator endIterator() const;
255
256         /*! \brief
257          * Adds a new variable symbol.
258          *
259          * \param[in] name   Name of the new symbol.
260          * \param[in] sel    Value of the variable.
261          * \throws    std::bad_alloc if out of memory.
262          * \throws    InvalidInputError if there was a symbol with the same
263          *      name.
264          */
265         void addVariable(const char                        *name,
266                          const SelectionTreeElementPointer &sel);
267         /*! \brief
268          * Adds a new method symbol.
269          *
270          * \param[in] name   Name of the new symbol.
271          * \param[in] method Method that this symbol represents.
272          * \throws    std::bad_alloc if out of memory.
273          * \throws    APIError if there was a symbol with the same name.
274          */
275         void addMethod(const char *name, gmx_ana_selmethod_t *method);
276
277     private:
278         class Impl;
279
280         PrivateImplPointer<Impl> impl_;
281
282         /*! \brief
283          * Needed to access implementation types.
284          */
285         friend class SelectionParserSymbolIterator;
286 };
287
288 } // namespace gmx
289
290 #endif