// // Copyright (C) 2002-2017 Greg Landrum and Rational Discovery LLC // // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include "AtomIterators.h" #include "RDKitBase.h" #include "RDKitQueries.h" namespace RDKit { template AtomIterator_::AtomIterator_(Mol_ *mol) { _mol = mol; _pos = 0; _max = mol->getNumAtoms(); }; template AtomIterator_::AtomIterator_(Mol_ *mol, int pos) { _mol = mol; _pos = pos; _max = mol->getNumAtoms(); }; template AtomIterator_::AtomIterator_( const AtomIterator_ &other) { _mol = other._mol; _pos = other._pos; _max = other._max; } template AtomIterator_ &AtomIterator_::operator=( const AtomIterator_ &other) { _mol = other._mol; _pos = other._pos; _max = other._max; return *this; } template AtomIterator_ &AtomIterator_::operator+=(int val) { _pos += val; if (_pos < 0 || _pos > _max) { _pos = _max; } return *this; } template AtomIterator_ &AtomIterator_::operator-=(int val) { _pos -= val; if (_pos < 0 || _pos > _max) { _pos = _max; } return *this; } template AtomIterator_ AtomIterator_::operator+( int val) const { AtomIterator_ res(*this); res += val; // += takes care of the pre/post conditions for us, so we're safe to return return res; } template AtomIterator_ AtomIterator_::operator-( int val) const { AtomIterator_ res(*this); // -= takes care of the pre/post conditions for us, so we're safe to return res -= val; return res; } // iterator subtraction template int AtomIterator_::operator-( AtomIterator_ &other) const { PRECONDITION(_mol == other._mol, "bad operator- call"); return _pos - other._pos; } // dereference template Atom_ *AtomIterator_::operator*() const { PRECONDITION(_mol != nullptr, "no molecule"); RANGE_CHECK(0, _pos, _max - 1); return (*_mol)[_pos]; } // random access template Atom_ *AtomIterator_::operator[](const int which) const { PRECONDITION(_mol != nullptr, "no molecule"); RANGE_CHECK(0, which, _max - 1); return (*_mol)[which]; } template bool AtomIterator_::operator==( const AtomIterator_ &other) const { return _mol == other._mol && _pos == other._pos; } template bool AtomIterator_::operator!=( const AtomIterator_ &other) const { return _mol != other._mol || _pos != other._pos; } template bool AtomIterator_::operator<( const AtomIterator_ &other) const { return _mol == other._mol && _pos < other._pos; } template bool AtomIterator_::operator<=( const AtomIterator_ &other) const { return _mol == other._mol && _pos <= other._pos; } template bool AtomIterator_::operator>( const AtomIterator_ &other) const { return _mol == other._mol && _pos > other._pos; } template bool AtomIterator_::operator>=( const AtomIterator_ &other) const { return _mol == other._mol && _pos >= other._pos; } // pre-increment template AtomIterator_ &AtomIterator_::operator++() { _pos++; return *this; } template AtomIterator_ AtomIterator_::operator++(int) { AtomIterator_ res(*this); _pos++; return res; } // pre-decrement template AtomIterator_ &AtomIterator_::operator--() { _pos--; return *this; } template AtomIterator_ AtomIterator_::operator--(int) { AtomIterator_ res(*this); if (_pos - 1 < 0) { _pos = _max; } else { _pos--; } return res; } //----------------------------------------- // // HeteroatomIterator // //----------------------------------------- template HeteroatomIterator_::HeteroatomIterator_(Mol_ *mol) { _mol = mol; _qA = new QueryAtom(6); _qA->getQuery()->setNegation(true); _end = mol->getNumAtoms(); _pos = _findNext(0); }; template HeteroatomIterator_::HeteroatomIterator_(Mol_ *mol, int pos) { _mol = mol; _qA = new QueryAtom(6); _end = mol->getNumAtoms(); _pos = pos; }; template HeteroatomIterator_::~HeteroatomIterator_() { delete _qA; _qA = nullptr; } template HeteroatomIterator_::HeteroatomIterator_(const ThisType &other) { _mol = other._mol; _end = other._end; _pos = other._pos; _qA = static_cast(other._qA->copy()); } template HeteroatomIterator_ &HeteroatomIterator_::operator=( const ThisType &other) { _mol = other._mol; _end = other._end; _pos = other._pos; _qA = static_cast(other._qA->copy()); return *this; } template bool HeteroatomIterator_::operator==(const ThisType &other) const { return _mol == other._mol && _pos == other._pos; } template bool HeteroatomIterator_::operator!=(const ThisType &other) const { return _mol != other._mol || _pos != other._pos; } template Atom_ *HeteroatomIterator_::operator*() const { PRECONDITION(_mol != nullptr, "no molecule"); return (*_mol)[_pos]; } // pre-increment template HeteroatomIterator_ &HeteroatomIterator_::operator++() { _pos = _findNext(_pos + 1); return *this; } template HeteroatomIterator_ HeteroatomIterator_::operator++( int) { HeteroatomIterator_ res(*this); _pos = _findNext(_pos + 1); return res; } // pre-decrement template HeteroatomIterator_ &HeteroatomIterator_::operator--() { _pos = _findPrev(_pos - 1); return *this; } template HeteroatomIterator_ HeteroatomIterator_::operator--( int) { HeteroatomIterator_ res(*this); _pos = _findPrev(_pos - 1); return res; } template int HeteroatomIterator_::_findNext(int from) { while (from < _end) { if (_qA->Match((*_mol)[from])) { break; } else { from++; } } return from; } template int HeteroatomIterator_::_findPrev(int from) { while (from > 0) { if (_qA->Match((*_mol)[from])) { break; } else { from--; } } if (from < 0) { from = _end; } return from; } //----------------------------------------- // // AromaticAtomIterator // //----------------------------------------- template AromaticAtomIterator_::AromaticAtomIterator_(Mol_ *mol) { _mol = mol; _end = mol->getNumAtoms(); _pos = _findNext(0); }; template AromaticAtomIterator_::AromaticAtomIterator_(Mol_ *mol, int pos) { _mol = mol; _end = mol->getNumAtoms(); _pos = pos; }; template AromaticAtomIterator_::~AromaticAtomIterator_() {} template AromaticAtomIterator_::AromaticAtomIterator_( const ThisType &other) { _mol = other._mol; _end = other._end; _pos = other._pos; } template AromaticAtomIterator_ &AromaticAtomIterator_::operator=(const ThisType &other) { _mol = other._mol; _end = other._end; _pos = other._pos; return *this; } template bool AromaticAtomIterator_::operator==( const ThisType &other) const { return _mol == other._mol && _pos == other._pos; } template bool AromaticAtomIterator_::operator!=( const ThisType &other) const { return _mol != other._mol || _pos != other._pos; } template Atom_ *AromaticAtomIterator_::operator*() const { PRECONDITION(_mol != nullptr, "no molecule"); return (*_mol)[_pos]; } // pre-increment template AromaticAtomIterator_ &AromaticAtomIterator_::operator++() { _pos = _findNext(_pos + 1); return *this; } template AromaticAtomIterator_ AromaticAtomIterator_::operator++(int) { AromaticAtomIterator_ res(*this); _pos = _findNext(_pos + 1); return res; } // pre-decrement template AromaticAtomIterator_ &AromaticAtomIterator_::operator--() { _pos = _findPrev(_pos - 1); return *this; } template AromaticAtomIterator_ AromaticAtomIterator_::operator--(int) { AromaticAtomIterator_ res(*this); _pos = _findPrev(_pos - 1); return res; } template int AromaticAtomIterator_::_findNext(int from) { while (from < _end) { if ((*_mol)[from]->getIsAromatic()) { break; } else { from++; } } return from; } template int AromaticAtomIterator_::_findPrev(int from) { while (from > 0) { if ((*_mol)[from]->getIsAromatic()) { break; } else { from--; } } if (from < 0) { from = _end; } return from; } //----------------------------------------- // // QueryAtomIterator // //----------------------------------------- template QueryAtomIterator_::QueryAtomIterator_(Mol_ *mol, QueryAtom const *what) { PRECONDITION(what, "bad query atom"); _mol = mol; _qA = static_cast(what->copy()); _end = mol->getNumAtoms(); _pos = _findNext(0); }; template QueryAtomIterator_::QueryAtomIterator_(Mol_ *mol, int pos) { _mol = mol; _qA = nullptr; _end = mol->getNumAtoms(); _pos = pos; }; template QueryAtomIterator_::~QueryAtomIterator_() { delete _qA; _qA = nullptr; } template QueryAtomIterator_::QueryAtomIterator_( const QueryAtomIterator_ &other) { _mol = other._mol; _pos = other._pos; _end = other._end; if (other._qA) { _qA = static_cast(other._qA->copy()); } else { _qA = nullptr; } } template QueryAtomIterator_ &QueryAtomIterator_::operator=( const QueryAtomIterator_ &other) { if (this != &other) { _mol = other._mol; _pos = other._pos; _end = other._end; delete _qA; if (other._qA) { _qA = static_cast(other._qA->copy()); } else { _qA = nullptr; } } return *this; } template bool QueryAtomIterator_::operator==( const QueryAtomIterator_ &other) const { return _mol == other._mol && _pos == other._pos; } template bool QueryAtomIterator_::operator!=( const QueryAtomIterator_ &other) const { return _mol != other._mol || _pos != other._pos; } template Atom_ *QueryAtomIterator_::operator*() const { PRECONDITION(_mol != nullptr, "no molecule"); return (*_mol)[_pos]; } // pre-increment template QueryAtomIterator_ &QueryAtomIterator_::operator++() { _pos = _findNext(_pos + 1); return *this; } template QueryAtomIterator_ QueryAtomIterator_::operator++( int) { QueryAtomIterator_ res(*this); _pos = _findNext(_pos + 1); return res; } // pre-decrement template QueryAtomIterator_ &QueryAtomIterator_::operator--() { _pos = _findPrev(_pos - 1); return *this; } template QueryAtomIterator_ QueryAtomIterator_::operator--( int) { QueryAtomIterator_ res(*this); _pos = _findPrev(_pos - 1); return res; } template int QueryAtomIterator_::_findNext(int from) { PRECONDITION(_mol != nullptr, "no molecule"); PRECONDITION(_qA != nullptr, "no query set"); while (from < _end) { if (_qA->Match((*_mol)[from])) { break; } else { from++; } } return from; } template int QueryAtomIterator_::_findPrev(int from) { PRECONDITION(_mol != nullptr, "no molecule"); PRECONDITION(_qA != nullptr, "no query set"); while (from > 0) { if (_qA->Match((*_mol)[from])) { break; } else { from--; } } if (from < 0) { from = _end; } return from; } //----------------------------------------- // // MatchingAtomIterator // //----------------------------------------- template MatchingAtomIterator_::MatchingAtomIterator_(Mol_ *mol, bool (*fn)(Atom_ *)) { PRECONDITION(fn, "bad query function"); _mol = mol; _qF = fn; _end = mol->getNumAtoms(); _pos = _findNext(0); }; template MatchingAtomIterator_::MatchingAtomIterator_(Mol_ *mol, int pos) { _mol = mol; _qF = nullptr; _end = mol->getNumAtoms(); _pos = pos; }; template MatchingAtomIterator_::~MatchingAtomIterator_() {} template MatchingAtomIterator_::MatchingAtomIterator_( const MatchingAtomIterator_ &other) { _mol = other._mol; _pos = other._pos; _end = other._end; _qF = other._qF; } template MatchingAtomIterator_ &MatchingAtomIterator_::operator=( const MatchingAtomIterator_ &other) { if (this != &other) { _mol = other._mol; _pos = other._pos; _end = other._end; _qF = other._qF; } return *this; } template bool MatchingAtomIterator_::operator==( const MatchingAtomIterator_ &other) const { return _mol == other._mol && _pos == other._pos; } template bool MatchingAtomIterator_::operator!=( const MatchingAtomIterator_ &other) const { return _mol != other._mol || _pos != other._pos; } template Atom_ *MatchingAtomIterator_::operator*() const { PRECONDITION(_mol != nullptr, "no molecule"); return (*_mol)[_pos]; } // pre-increment template MatchingAtomIterator_ &MatchingAtomIterator_::operator++() { _pos = _findNext(_pos + 1); return *this; } template MatchingAtomIterator_ MatchingAtomIterator_::operator++(int) { MatchingAtomIterator_ res(*this); _pos = _findNext(_pos + 1); return res; } // pre-decrement template MatchingAtomIterator_ &MatchingAtomIterator_::operator--() { _pos = _findPrev(_pos - 1); return *this; } template MatchingAtomIterator_ MatchingAtomIterator_::operator--(int) { MatchingAtomIterator_ res(*this); _pos = _findPrev(_pos - 1); return res; } template int MatchingAtomIterator_::_findNext(int from) { PRECONDITION(_mol != nullptr, "no molecule"); PRECONDITION(_qF != nullptr, "no query set"); while (from < _end) { if (_qF((*_mol)[from])) { break; } else { ++from; } } return from; } template int MatchingAtomIterator_::_findPrev(int from) { PRECONDITION(_mol != nullptr, "no molecule"); PRECONDITION(_qF != nullptr, "no query set"); while (from > 0) { if (_qF((*_mol)[from])) { break; } else { --from; } } if (from < 0) { from = _end; } return from; } template class AtomIterator_; template class AtomIterator_; template class AromaticAtomIterator_; template class AromaticAtomIterator_; template class HeteroatomIterator_; template class HeteroatomIterator_; template class QueryAtomIterator_; template class QueryAtomIterator_; template class MatchingAtomIterator_; template class MatchingAtomIterator_; }; // namespace RDKit