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