/src/openbabel/include/openbabel/obiter.h
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************** |
2 | | obiter.h - STL-style iterators for Open Babel. |
3 | | |
4 | | Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc. |
5 | | Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison |
6 | | |
7 | | This file is part of the Open Babel project. |
8 | | For more information, see <http://openbabel.org/> |
9 | | |
10 | | This program is free software; you can redistribute it and/or modify |
11 | | it under the terms of the GNU General Public License as published by |
12 | | the Free Software Foundation version 2 of the License. |
13 | | |
14 | | This program 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 |
17 | | GNU General Public License for more details. |
18 | | ***********************************************************************/ |
19 | | |
20 | | #ifndef OB_OBITER_H |
21 | | #define OB_OBITER_H |
22 | | |
23 | | #include <openbabel/babelconfig.h> |
24 | | #include <openbabel/bitvec.h> |
25 | | #include <openbabel/mol.h> |
26 | | #include <openbabel/atom.h> |
27 | | #include <openbabel/bond.h> |
28 | | |
29 | | #include <vector> |
30 | | #include <stack> |
31 | | #include <queue> |
32 | | |
33 | | |
34 | | namespace OpenBabel |
35 | | { |
36 | | class OBMol; |
37 | | class OBAtom; |
38 | | class OBBond; |
39 | | class OBResidue; |
40 | | |
41 | | // more detailed descriptions and documentation in obiter.cpp |
42 | | |
43 | | //! \brief Iterate over all atoms in an OBMol |
44 | | class OBAPI OBMolAtomIter { |
45 | | std::vector<OBAtom*>::iterator _i; |
46 | | OBMol *_parent; |
47 | | OBAtom *_ptr; |
48 | | public: |
49 | | |
50 | 0 | OBMolAtomIter() :_parent(nullptr), _ptr(nullptr) { } |
51 | | OBMolAtomIter(OBMol *mol); |
52 | | OBMolAtomIter(OBMol &mol); |
53 | | OBMolAtomIter(const OBMolAtomIter &ai); |
54 | 0 | ~OBMolAtomIter() { } |
55 | | |
56 | | OBMolAtomIter& operator=(const OBMolAtomIter &ai); |
57 | | //! \return Whether the iterator can still advance (i.e., visit more atoms) |
58 | 0 | operator bool() const { return _ptr != nullptr; } |
59 | | //! Preincrement iterator -- advance to next atom and return |
60 | | OBMolAtomIter& operator++(); |
61 | | //! Postincrement iterator -- return the current atom and advance |
62 | | OBMolAtomIter operator++(int); |
63 | | //! \return a pointer to the current atom |
64 | 0 | OBAtom* operator->() const { return _ptr; } |
65 | | //! \return a reference to the current atom |
66 | 0 | OBAtom& operator*() const { return *_ptr; } |
67 | | }; |
68 | | |
69 | | //! \brief Iterate over all atoms in an OBMol in a depth-first search (DFS) |
70 | | class OBAPI OBMolAtomDFSIter { |
71 | | OBMol *_parent; |
72 | | OBAtom *_ptr; |
73 | | OBBitVec _notVisited; |
74 | | std::stack<OBAtom *> _stack; |
75 | | public: |
76 | | |
77 | 0 | OBMolAtomDFSIter() : _parent(nullptr), _ptr(nullptr) { } |
78 | | OBMolAtomDFSIter(OBMol *mol, int StartIndex=1); |
79 | | OBMolAtomDFSIter(OBMol &mol, int StartIndex=1); |
80 | | OBMolAtomDFSIter(const OBMolAtomDFSIter &ai); |
81 | 0 | ~OBMolAtomDFSIter() { } |
82 | | |
83 | | OBMolAtomDFSIter& operator=(const OBMolAtomDFSIter &ai); |
84 | | //! \return Whether the iterator can still advance (i.e., visit more atoms) |
85 | 0 | operator bool() const { return _ptr != nullptr; } |
86 | | //! Preincrement -- advance to the next atom in the DFS list and return |
87 | | OBMolAtomDFSIter& operator++(); |
88 | | //! Postincrement -- return the current atom and advance to the next atom |
89 | | OBMolAtomDFSIter operator++(int); |
90 | | //! \return a pointer to the current atom |
91 | 0 | OBAtom* operator->() const { return _ptr; } |
92 | | //! \return a reference to the current atom |
93 | 0 | OBAtom& operator*() const { return *_ptr; } |
94 | | /// \return NULL if at the last atom in a fragment, else the next atom |
95 | | OBAtom* next() |
96 | 0 | { |
97 | 0 | if(_stack.empty()) |
98 | 0 | return nullptr; //end of a disconnected fragment |
99 | 0 | else |
100 | 0 | return _stack.top(); //the next atom |
101 | 0 | } |
102 | | }; |
103 | | |
104 | | //! \brief Iterate over all atoms in an OBMol in a breadth-first search (BFS) |
105 | | class OBAPI OBMolAtomBFSIter { |
106 | | OBMol *_parent; |
107 | | OBAtom *_ptr; |
108 | | OBBitVec _notVisited; |
109 | | std::queue<OBAtom *> _queue; |
110 | | std::vector<int> _depth; |
111 | | public: |
112 | | |
113 | 0 | OBMolAtomBFSIter(): _parent(nullptr), _ptr(nullptr) { } |
114 | | OBMolAtomBFSIter(OBMol *mol, int StartIndex = 1); |
115 | | OBMolAtomBFSIter(OBMol &mol, int StartIndex = 1); |
116 | | OBMolAtomBFSIter(const OBMolAtomBFSIter &ai); |
117 | 0 | ~OBMolAtomBFSIter() { } |
118 | | |
119 | | OBMolAtomBFSIter& operator=(const OBMolAtomBFSIter &ai); |
120 | | //! \return Whether the iterator can still advance (i.e., visit more atoms) |
121 | 0 | operator bool() const { return _ptr != nullptr; } |
122 | | //! Preincrement -- advance to the next atom in the BFS list and return |
123 | | OBMolAtomBFSIter& operator++(); |
124 | | //! Postincrement -- return the current atom and advance to the next atom |
125 | | OBMolAtomBFSIter operator++(int); |
126 | | //! \return a pointer to the current atom |
127 | 0 | OBAtom* operator->() const { return _ptr; } |
128 | | //! \return a reference to the current atom |
129 | 0 | OBAtom& operator*() const { return *_ptr; } |
130 | | //! \return the current depth of the iterator |
131 | | //! \since version 2.2 |
132 | | int CurrentDepth() const; |
133 | | }; |
134 | | |
135 | | //! \brief Iterate over all bonds in an OBMol in a breadth-first search (BFS) |
136 | | class OBAPI OBMolBondBFSIter { |
137 | | OBMol *_parent; |
138 | | OBBond *_ptr; |
139 | | OBBitVec _notVisited; |
140 | | std::queue<OBBond *> _queue; |
141 | | std::vector<int> _depth; |
142 | | public: |
143 | | |
144 | 0 | OBMolBondBFSIter(): _parent(nullptr), _ptr(nullptr) { } |
145 | | OBMolBondBFSIter(OBMol *mol, int StartIndex = 0); |
146 | | OBMolBondBFSIter(OBMol &mol, int StartIndex = 0); |
147 | | OBMolBondBFSIter(const OBMolBondBFSIter &ai); |
148 | 0 | ~OBMolBondBFSIter() { } |
149 | | |
150 | | OBMolBondBFSIter& operator=(const OBMolBondBFSIter &ai); |
151 | | //! \return Whether the iterator can still advance (i.e., visit more atoms) |
152 | 0 | operator bool() const { return _ptr != nullptr; } |
153 | | //! Preincrement -- advance to the next atom in the BFS list and return |
154 | | OBMolBondBFSIter& operator++(); |
155 | | //! Postincrement -- return the current atom and advance to the next atom |
156 | | OBMolBondBFSIter operator++(int); |
157 | | //! \return a pointer to the current atom |
158 | 0 | OBBond* operator->() const { return _ptr; } |
159 | | //! \return a reference to the current atom |
160 | 0 | OBBond& operator*() const { return *_ptr; } |
161 | | //! \return the current depth of the iterator |
162 | | //! \since version 2.2 |
163 | | int CurrentDepth() const; |
164 | | }; |
165 | | |
166 | | //! \brief Iterate over all bonds in an OBMol |
167 | | class OBAPI OBMolBondIter { |
168 | | std::vector<OBBond*>::iterator _i; |
169 | | OBMol *_parent; |
170 | | OBBond *_ptr; |
171 | | public: |
172 | | |
173 | 0 | OBMolBondIter() : _parent(nullptr), _ptr(nullptr) {} |
174 | | OBMolBondIter(OBMol *mol); |
175 | | OBMolBondIter(OBMol &mol); |
176 | | OBMolBondIter(const OBMolBondIter &bi); |
177 | 0 | ~OBMolBondIter() { } |
178 | | |
179 | | OBMolBondIter& operator=(const OBMolBondIter &bi); |
180 | | //! \return Whether the iterator can still advance (i.e., visit more bonds) |
181 | 0 | operator bool() const { return _ptr != nullptr; } |
182 | | //! Preincrement -- advance to the next bond and return |
183 | | OBMolBondIter& operator++(); |
184 | | //! Postincrement -- return the current bond and advance to the next |
185 | | OBMolBondIter operator++(int); |
186 | | //! \return a pointer to the current bond |
187 | 0 | OBBond* operator->() const { return _ptr; } |
188 | | //! \return a reference to the current bond |
189 | 0 | OBBond& operator*() const { return *_ptr; } |
190 | | }; |
191 | | |
192 | | //! \brief Iterate over all neighboring atoms to an OBAtom |
193 | | class OBAPI OBAtomAtomIter { |
194 | | std::vector<OBBond*>::iterator _i; |
195 | | OBAtom *_parent; |
196 | | OBAtom *_ptr; |
197 | | public: |
198 | | |
199 | 0 | OBAtomAtomIter() : _parent(nullptr), _ptr(nullptr) { } |
200 | | OBAtomAtomIter(OBAtom *atm); |
201 | | OBAtomAtomIter(OBAtom &atm); |
202 | | OBAtomAtomIter(const OBAtomAtomIter &ai); |
203 | 0 | ~OBAtomAtomIter() { } |
204 | | |
205 | | OBAtomAtomIter& operator=(const OBAtomAtomIter &ai); |
206 | | //! \return Whether the iterator can still advance (i.e., visit more neighbors) |
207 | 0 | operator bool() const { return _ptr != nullptr; } |
208 | | //! Preincrement -- advance to the next neighbor and return |
209 | | OBAtomAtomIter& operator++(); |
210 | | //! Postincrement -- return the current neighbor and advance to the next |
211 | | OBAtomAtomIter operator++(int); |
212 | | //! \return a pointer to the current atom |
213 | 0 | OBAtom* operator->() const { return _ptr; } |
214 | | //! \return a reference to the current atom |
215 | 0 | OBAtom& operator*() const { return *_ptr; } |
216 | | }; |
217 | | |
218 | | //! \brief Iterate over all bonds on an OBAtom |
219 | | class OBAPI OBAtomBondIter { |
220 | | std::vector<OBBond*>::iterator _i; |
221 | | OBAtom *_parent; |
222 | | OBBond *_ptr; |
223 | | public: |
224 | | |
225 | 0 | OBAtomBondIter(): _parent(nullptr), _ptr(nullptr) { } |
226 | | OBAtomBondIter(OBAtom *atm); |
227 | | OBAtomBondIter(OBAtom &atm); |
228 | | OBAtomBondIter(const OBAtomBondIter &bi); |
229 | 0 | ~OBAtomBondIter() { } |
230 | | |
231 | | OBAtomBondIter& operator=(const OBAtomBondIter &bi); |
232 | | //! \return Whether the iterator can still advance (i.e., visit more bonds) |
233 | 0 | operator bool() const { return _ptr != nullptr; } |
234 | | //! Preincrement -- advance to the next bond and return |
235 | | OBAtomBondIter& operator++(); |
236 | | //! Postincrement -- return the current state and advance to the next bond |
237 | | OBAtomBondIter operator++(int); |
238 | | //! \return a pointer to the current bond |
239 | 0 | OBBond* operator->() const { return _ptr; } |
240 | | //! \return a reference to the current bond |
241 | 0 | OBBond& operator*() const { return *_ptr;} |
242 | | }; |
243 | | |
244 | | //! \brief Iterate over all residues in an OBMol |
245 | | class OBAPI OBResidueIter { |
246 | | std::vector<OBResidue*>::iterator _i; |
247 | | OBResidue *_ptr; |
248 | | OBMol *_parent; |
249 | | public: |
250 | | |
251 | 0 | OBResidueIter() : _ptr(nullptr), _parent(nullptr) { } |
252 | | OBResidueIter(OBMol *mol); |
253 | | OBResidueIter(OBMol &mol); |
254 | | OBResidueIter(const OBResidueIter &ri); |
255 | 0 | ~OBResidueIter() { } |
256 | | |
257 | | OBResidueIter& operator=(const OBResidueIter &ri); |
258 | | //! \return Whether the iterator can still advance (i.e., visit more residues) |
259 | 0 | operator bool() const { return _ptr != nullptr; } |
260 | | //! Preincrement -- advance to the next residue and return |
261 | | OBResidueIter& operator++(); |
262 | | //! Postincrement -- return the current state and advance to the next residue |
263 | | OBResidueIter operator++(int); |
264 | | //! \return a pointer to the current residue |
265 | 0 | OBResidue* operator->() const{ return _ptr; } |
266 | | //! \return a reference to the current residue |
267 | 0 | OBResidue& operator*() const { return *_ptr;} |
268 | | }; |
269 | | |
270 | | //! \brief Iterate over all atoms in an OBResidue |
271 | | class OBAPI OBResidueAtomIter { |
272 | | std::vector<OBAtom*>::iterator _i; |
273 | | OBResidue *_parent; |
274 | | OBAtom *_ptr; |
275 | | public: |
276 | | |
277 | 0 | OBResidueAtomIter() : _parent(nullptr), _ptr(nullptr) { } |
278 | | OBResidueAtomIter(OBResidue *res); |
279 | | OBResidueAtomIter(OBResidue &res); |
280 | | OBResidueAtomIter(const OBResidueAtomIter &ri); |
281 | 0 | ~OBResidueAtomIter() { } |
282 | | |
283 | | OBResidueAtomIter &operator = (const OBResidueAtomIter &ri); |
284 | | //! \return Whether the iterator can still advance (i.e., visit more atoms in this residue) |
285 | 0 | operator bool() const { return _ptr != nullptr; } |
286 | | //! Preincrement -- advance to the next atom (if any) and return |
287 | | OBResidueAtomIter& operator++ (); |
288 | | //! Postincrement -- return the current state and advance to the next atom (if any) |
289 | | OBResidueAtomIter operator++ (int); |
290 | | //! \return a pointer to the current atom |
291 | 0 | OBAtom *operator->() const { return _ptr; } |
292 | | //! \return a reference to the current atom |
293 | 0 | OBAtom &operator*() const { return *_ptr;} |
294 | | }; |
295 | | |
296 | | //! \brief Iterate over all angles in an OBMol |
297 | | class OBAPI OBMolAngleIter { |
298 | | OBMol *_parent; |
299 | | std::vector<std::vector<unsigned int> > _vangle; |
300 | | std::vector<std::vector<unsigned int> >::iterator _i; |
301 | | std::vector<unsigned int> _angle; |
302 | | public: |
303 | | |
304 | 0 | OBMolAngleIter() :_parent(nullptr) { } |
305 | | OBMolAngleIter(OBMol *mol); |
306 | | OBMolAngleIter(OBMol &mol); |
307 | | OBMolAngleIter(const OBMolAngleIter &ai); |
308 | 0 | ~OBMolAngleIter() { } |
309 | | |
310 | | OBMolAngleIter& operator=(const OBMolAngleIter &ai); |
311 | | //! \return Whether the iterator can still advance (i.e., visit more angles) |
312 | 0 | operator bool() const { return (_i != _vangle.end()); } |
313 | | //! Preincrement -- advance to the next angle and return |
314 | | OBMolAngleIter& operator++(); |
315 | | //! \return A vector of three atom indexes specifying the angle |
316 | | //! \see OBAtom::GetIdx() |
317 | 0 | std::vector<unsigned int> operator*() const { return _angle; } |
318 | | }; |
319 | | |
320 | | //! \brief Iterate over all torsions in an OBMol |
321 | | class OBAPI OBMolTorsionIter { |
322 | | OBMol *_parent; |
323 | | std::vector<std::vector<unsigned int> > _vtorsion; |
324 | | std::vector<std::vector<unsigned int> >::iterator _i; |
325 | | std::vector<unsigned int> _torsion; |
326 | | public: |
327 | | |
328 | 0 | OBMolTorsionIter() :_parent(nullptr) { } |
329 | | OBMolTorsionIter(OBMol *mol); |
330 | | OBMolTorsionIter(OBMol &mol); |
331 | | OBMolTorsionIter(const OBMolTorsionIter &ai); |
332 | 0 | ~OBMolTorsionIter() { } |
333 | | |
334 | | OBMolTorsionIter& operator=(const OBMolTorsionIter &ai); |
335 | | //! \return Whether the iterator can still advance (i.e., visit more torsions) |
336 | 0 | operator bool() const { return (_i != _vtorsion.end()); } |
337 | | //! Preincrement -- advance to the next torsion and return |
338 | | OBMolTorsionIter& operator++(); |
339 | | //! \return A vector of four atom indexes specifying the torsion |
340 | | //! \see OBAtom::GetIdx() |
341 | 0 | std::vector<unsigned int> operator*() const { return _torsion; } |
342 | | }; |
343 | | |
344 | | //! \brief Iterate over all pairs of atoms (>1-4) in an OBMol |
345 | | class OBAPI OBMolPairIter { |
346 | | std::vector<OBAtom*>::iterator _i; |
347 | | std::vector<OBAtom*>::iterator _j; |
348 | | OBMol *_parent; |
349 | | //std::vector<std::vector<unsigned int> > _vpair; |
350 | | //std::vector<std::vector<unsigned int> >::iterator _i; |
351 | | std::vector<unsigned int> _pair; |
352 | | |
353 | | public: |
354 | | |
355 | 0 | OBMolPairIter() :_parent(nullptr) { } |
356 | | OBMolPairIter(OBMol *mol); |
357 | | OBMolPairIter(OBMol &mol); |
358 | | OBMolPairIter(const OBMolPairIter &ai); |
359 | 0 | ~OBMolPairIter() { } |
360 | | |
361 | | OBMolPairIter& operator=(const OBMolPairIter &ai); |
362 | | //! \return Whether the iterator can still advance (i.e., visit more 1-4 atom pairs) |
363 | 0 | operator bool() const { return _pair.size()>0; } |
364 | | //! Preincrement -- advance to the next 1-4 atom pair and return |
365 | | OBMolPairIter& operator++(); |
366 | | //! \return A vector of two atom indexes specifying the 1-4 atom pair |
367 | | //! \see OBAtom::GetIdx() |
368 | 0 | std::vector<unsigned int> operator*() const { return _pair; } |
369 | | }; |
370 | | |
371 | | class OBRing; |
372 | | class OBRingData; |
373 | | |
374 | | //! \brief Iterate over all rings in an OBMol |
375 | | class OBAPI OBMolRingIter { |
376 | | std::vector<OBRing*>::iterator _i; |
377 | | OBRing *_ptr; |
378 | | OBMol *_parent; |
379 | | OBRingData *_rings; |
380 | | public: |
381 | | |
382 | 0 | OBMolRingIter() : _ptr(nullptr), _parent(nullptr), _rings(nullptr) { } |
383 | | OBMolRingIter(OBMol *mol); |
384 | | OBMolRingIter(OBMol &mol); |
385 | | OBMolRingIter(const OBMolRingIter &ri); |
386 | 0 | ~OBMolRingIter() { } |
387 | | |
388 | | OBMolRingIter& operator=(const OBMolRingIter &ri); |
389 | | //! \return Whether the iterator can advance (i.e., there are more rings) |
390 | 0 | operator bool() const { return _ptr != nullptr; } |
391 | | //! Preincrement -- advance to the next ring (if any) and return |
392 | | OBMolRingIter& operator++(); |
393 | | //! Postincrement -- return the current state and advance to the next ring |
394 | | OBMolRingIter operator++(int); |
395 | | //! \return A pointer to the current ring (if any) |
396 | 0 | OBRing* operator->() const { return _ptr; } |
397 | | //! \return A reference to the current ring (if any) |
398 | 0 | OBRing& operator*() const { return *_ptr;} |
399 | | }; |
400 | | |
401 | | namespace impl { |
402 | | |
403 | 21.7k | inline OBMolAtomRange MolGetAtoms(const OpenBabel::OBMol &mol) { return mol.GetAtoms(); } |
404 | 5.47k | inline OBMolAtomRange MolGetAtoms(const OpenBabel::OBMol *mol) { return mol->GetAtoms(); } |
405 | | |
406 | 10.4k | inline OBMolBondRange MolGetBonds(const OpenBabel::OBMol &mol) { return mol.GetBonds(); } |
407 | 0 | inline OBMolBondRange MolGetBonds(const OpenBabel::OBMol *mol) { return mol->GetBonds(); } |
408 | | |
409 | 0 | inline OBAtomBondRange AtomGetBonds(const OpenBabel::OBAtom &atom) { return atom.GetBonds(); } |
410 | 1.61k | inline OBAtomBondRange AtomGetBonds(const OpenBabel::OBAtom *atom) { return atom->GetBonds(); } |
411 | | |
412 | 0 | inline OBAtomAtomRange AtomGetNbrs(const OpenBabel::OBAtom &atom) { return atom.GetNbrs(); } |
413 | 1.23k | inline OBAtomAtomRange AtomGetNbrs(const OpenBabel::OBAtom *atom) { return atom->GetNbrs(); } |
414 | | |
415 | | } |
416 | | |
417 | 27.2k | #define FOR_ATOMS_OF_MOL(a,m) for (auto a : impl::MolGetAtoms(m)) |
418 | 10.4k | #define FOR_BONDS_OF_MOL(b,m) for (auto b : impl::MolGetBonds(m)) |
419 | 1.23k | #define FOR_NBORS_OF_ATOM(a,p) for (auto a : impl::AtomGetNbrs(p)) |
420 | 1.61k | #define FOR_BONDS_OF_ATOM(b,p) for (auto b : impl::AtomGetBonds(p)) |
421 | 0 | #define FOR_RESIDUES_OF_MOL(r,m) for( OpenBabel::OBResidueIter r(m); r; ++r ) |
422 | 0 | #define FOR_ATOMS_OF_RESIDUE(a,r) for( OpenBabel::OBResidueAtomIter a(r); a; ++a ) |
423 | 0 | #define FOR_DFS_OF_MOL(a,m) for( OpenBabel::OBMolAtomDFSIter a(m); a; ++a ) |
424 | | #define FOR_BFS_OF_MOL(a,m) for( OpenBabel::OBMolAtomBFSIter a(m); a; ++a ) |
425 | 0 | #define FOR_BONDBFS_OF_MOL(b,m) for( OpenBabel::OBMolBondBFSIter b(m); b; ++b ) |
426 | 0 | #define FOR_RINGS_OF_MOL(r,m) for( OpenBabel::OBMolRingIter r(m); r; ++r ) |
427 | 0 | #define FOR_ANGLES_OF_MOL(a,m) for( OpenBabel::OBMolAngleIter a(m); a; ++a ) |
428 | 0 | #define FOR_TORSIONS_OF_MOL(t,m) for( OpenBabel::OBMolTorsionIter t(m); t; ++t ) |
429 | 0 | #define FOR_PAIRS_OF_MOL(p,m) for( OpenBabel::OBMolPairIter p(m); p; ++p ) |
430 | | |
431 | | } // namespace OpenBabel |
432 | | #endif // OB_OBITER_H |
433 | | |
434 | | //! \file obiter.h |
435 | | //! \brief STL-style iterators for Open Babel. |