Coverage Report

Created: 2025-07-11 06:49

/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.